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

时间:2009-04-01 15:29:54

标签: c++ g++ solaris

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

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

//testClass.cpp
testClass::testClass(const int * const x) {}

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

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

4 个答案:

答案 0 :(得分: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)
{
}

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

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

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

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

  

“任何cv-qualifier修改   参数类型被删除...这样   cv-qualifiers只影响   使用的定义参数   身体的功能;他们不   影响功能类型“

答案 1 :(得分: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)
     

-end example]

所以,这绝对没问题。

答案 2 :(得分:4)

将其视为

之间的相同区别
//testClass.hpp
class testClass {
  public:
     testClass(const int x);
};

//testClass.cpp
testClass::testClass(int x) {}

哪个也编译。您不能基于pass-by-value参数的常量进行重载。想象一下这个案例:

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

int main()
{
   f(7); // Which gets called?
}

来自标准:

  

不同的参数声明   只有在有或没有的情况下   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)
  

-end example]只有const和   volatile的类型说明符   参数类型的最外层   规范在此被忽略   时尚;常量和不稳定   埋藏在一个中的类型说明符   参数类型规范是   重要的,可以用来   区分重载功能   声明.112)特别是,   对于任何类型T,“指向T的指针”   “指向const T的指针”和“指向   挥发性T“被认为是不同的   参数类型,“参考   T,“”引用const T,“和   “提到挥发性T。”

答案 3 :(得分:0)

const int * const xconst int * x不一样,因为你已经制作了const?