构造函数定义和声明之间不匹配

Mik*_*keT 5 c++ solaris g++

我有以下C++代码,其中声明中我的构造函数的参数具有与构造函数的定义不同的常量.

//testClass.hpp
class testClass {
  public:
     testClass(const int *x);
};

//testClass.cpp
testClass::testClass(const int * const x) {}
Run Code Online (Sandbox Code Playgroud)

我能够使用g ++编译这个没有警告,如果这个代码编译或至少给出一些警告?事实证明,64位solaris上的内置C++编译器给了我一个链接器错误,这就是我注意到存在问题的方式.

在这种情况下匹配参数的规则是什么?这取决于编译器吗?

Bri*_*ndy 7

在这种情况下,允许从声明中省略const说明符,因为它不会为调用者改变任何内容.

它仅对实现细节的上下文有意义.这就是为什么它在定义而不是声明.

例:

//Both f and g have the same signature
void f(int x);
void g(const int x);

void f(const int x)//this is allowed
{
}

void g(const int x)
{
}
Run Code Online (Sandbox Code Playgroud)

任何调用f的人都不会在意你将它视为const,因为它是你自己的变量副本.

使用int*const x,它是相同的,它是指针的副本.是否可以指向其他内容对调用者无关紧要.

如果你在const int*const中省略了第一个const,那么这会有所不同,因为如果你更改它所指向的数据,它对调用者很重要.

参考:C++标准,8.3.5第3段:

"删除修改参数类型的任何cv限定符...这样的cv限定符仅影响函数体的参数定义;它们不影响函数类型"


Ecl*_*pse 5

把它想象成相同的区别

//testClass.hpp
class testClass {
  public:
     testClass(const int x);
};

//testClass.cpp
testClass::testClass(int x) {}
Run Code Online (Sandbox Code Playgroud)

这也编译。您不能根据传值参数的常量性进行重载。想象一下这个案例:

void f(int x) { }
void f(const int x) { } // Can't compile both of these.

int main()
{
   f(7); // Which gets called?
}
Run Code Online (Sandbox Code Playgroud)

从标准:

仅在存在或不存在 const 和/或 volatile 时不同的参数声明是等效的。也就是说,在确定要声明、定义或调用哪个函数时,将忽略每个参数类型的 const 和 volatile 类型说明符。[例子:

typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { ... } // definition of f(int)
int f (cInt) { ... } // error: redefinition of f(int)
Run Code Online (Sandbox Code Playgroud)

—结束示例] 以这种方式仅忽略参数类型规范最外层的 const 和 volatile 类型说明符;埋在参数类型规范中的 const 和 volatile 类型说明符很重要,可用于区分重载函数声明。112) 特别是,对于任何类型 T,“指向 T 的指针”、“指向 const T 的指针”和“指针to volatile T”被认为是不同的参数类型,“对 T 的引用”、“对 const T 的引用”和“对 volatile T 的引用”也是如此。


Ric*_*den 5

重载决议部分13.1/3b4中明确介绍了此示例:

仅存在或不存在const和/或volatile的参数声明是等效的.也就是说,在确定声明,定义或调用哪个函数时,将忽略每个参数类型的const和volatile类型说明符.

[例:

typedef const int cInt;
int f (int);
int f (const int); // redeclaration of f(int)
int f (int) { ... } // definition of f(int)
int f (cInt) { ... } // error: redefinition of f(int)
Run Code Online (Sandbox Code Playgroud)

- 末端的例子]

所以,这绝对没问题.