一个奇怪的 C++ 错误:test.cpp:15: 错误:将 'const *' 作为 '*' 的 'this' 参数丢弃限定符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/550428/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 15:54:05  来源:igfitidea点击:

An odd C++ error: test.cpp:15: error: passing ‘const *’ as ‘this’ argument of ‘*’ discards qualifiers

c++compiler-errorsconst

提问by FurtiveFelon

I'm having some trouble with a particular piece of code, if anyone can enlighten me on this matter it would be greatly appreciated, I've isolated the problem down in the following sample:

我在处理一段特定的代码时遇到了一些问题,如果有人能在这件事上启发我,我将不胜感激,我已经在以下示例中隔离了这个问题:

#include <iostream>

using namespace std;

class testing{
   int test();
   int test1(const testing& test2);
};

int testing::test(){
   return 1;
}

int testing::test1(const testing& test2){
   test2.test();
   return 1;
}

So what could possibly have cause the following error:

那么什么可能导致以下错误:

test.cpp:15: error: passing ‘const testing' as ‘this' argument of ‘int testing::test()' discards qualifiers

test.cpp:15: 错误:将“const testing”作为“int testing::test()”的“this”参数传递会丢弃限定符

Thanks a lot!

非常感谢!

回答by Tom Alsberg

The problem is calling a non-constfunction test2.test()on a constobject test2from testing::test1.

问题是调用非const功能test2.test()一上const对象test2testing::test1

testing::test1gets test2as a parameter const testing &test2. So within testing::test1, test2const. Then in the first line of the function:

testing::test1test2作为参数获取const testing &test2。所以在testing::test1, test2const. 然后在函数的第一行:

test2.test()

The testing::testfunction is called on test2. That function is not declared with constat the signature end, so it may modify the object it is called on (the thispointer implicitly passed to it), and even though it does not, the compiler assumes so. By letting you call it there, the compiler would let you modify a constvariable without an explicit cast, which C++ is not supposed to allow. Therefore to explain the error message:

testing::test函数在 上调用test2。该函数没有const在签名结束时声明,因此它可能会修改它被调用的对象(this隐式传递给它的指针),即使它没有,编译器也会假设这样做。通过让你在那里调用它,编译器会让你修改一个const没有显式转换的变量,这是 C++ 不允许的。 因此要解释错误消息

test.cpp:15: error: passing ‘const testing' as ‘this' argument of ‘int testing::test()' discards qualifiers

thisrefers to the object the member function (testing::test) operates on, and in this case it is not const, because testing::testwas not declared with const, and thus the mismatch is detected when trying to make a non-constpointer (this) refer to a constobject (testing), ignoring the constqualifier.

this指的是成员函数 ( testing::test) 操作的对象,在这种情况下它不是const,因为testing::test没有用 声明const,因此在尝试使非const指针 ( this) 引用const对象 ( testing)时检测到不匹配,忽略在const预选赛

To solve this, decide whether the testing::testfunction should ever need to modify the object it is called on (the way it is written now it does not, as all it does is return 1, however that may change, so you need to think at what its intended functionality is). If it should, then obviously calling it on a constobject is bad, although you can use const_castto ask the compiler to override that, but this is dangerous. If it should not, then mark it const, so that it can be called on constobjects as well:

为了解决这个问题,决定testing::test函数是否需要修改它被调用的对象(现在它的编写方式不需要,因为它所做的是return 1,但是这可能会改变,所以你需要考虑它的意图功能是)。如果应该,那么显然在const对象上调用它是不好的,尽管您可以使用const_cast要求编译器覆盖它,但这是危险的。如果不应该,则标记它const,以便它也可以在const对象上调用:

class testing{
    int test1() const;
    // ...
}

int testing::test() const {
    // ...
}

回答by Brian R. Bondy

Because of the definition of the member function test1:

因为成员函数test1的定义:

int testing::test1(const testing& test2){
   test2.test();
   return 1;
}

You are passing in a const reference of for the variable test2.

您正在为变量 test2 传递一个常量引用。

That means that you cannot modify any member of test2 and you cannot call any member function that is not const or is not static.

这意味着您不能修改 test2 的任何成员,也不能调用任何非 const 或非静态的成员函数。

Here is how you can fix:

以下是您可以修复的方法:

int testing::test() const {
   return 1;
}

The extra const at the end tells the compiler that you are not planning on modifying the content of the current object (and if you do you will get a different compiling error).

最后的额外 const 告诉编译器你不打算修改当前对象的内容(如果你这样做了,你会得到一个不同的编译错误)。

回答by Himadri Choudhury

The line: test2.test()

该行: test2.test()

is calling a non const function, even though test2 is a const reference. That's the problem. You can fix this by making testing::test a const function.

正在调用一个非 const 函数,即使 test2 是一个 const 引用。那就是问题所在。您可以通过将 testing::test 设为 const 函数来解决此问题。

回答by goldPseudo

testing::test1(const testing& test2) is expecting the passed object to be const, and it will give you an error if you either modify the values of it's variables, or access any methods thereof that are not explicitly defined as const.

testing::test1(const testing& test2) 期望传递的对象是const,如果你修改它的变量的值,或者访问任何没有明确定义为const的方法,它都会给你一个错误。

Since the test() method doesn't actually change any data, best practice is to set it const, as follows:

由于 test() 方法实际上不会更改任何数据,因此最佳做法是将其设置为 const,如下所示:

class testing{
   int test() const;
   int test1(const testing& test2);
};

int testing::test() const {
   return 1;
}

Alternatively, just remove the word const when defining the arguments for test1(), and it will allow you to access any of the passed object's methods at your leisure.

或者,只需在定义 test1() 的参数时删除 const 一词,它就会允许您随意访问任何传递对象的方法。

回答by bio

For a quick and dirt solution, try compiling with -fpermissiveas often suggested by the compiler itself (which is probably what VisualStudio compilers do, being that Windows users seldom report this problem).

要获得快速和肮脏的解决方案,请尝试-fpermissive按照编译器本身建议的方式进行编译(这可能是 VisualStudio 编译器所做的,因为 Windows 用户很少报告此问题)。