显式复制构造函数会在 C++ 中产生编译错误。谁负责铸造?
Explicit on copy constructor makes compilation error in c++. Who is responsible for casting?
我的 Clion IDE 告诉我,当我将 const double*
类型传输到具有参数 const A
且定义了 A
的函数时可能会出现问题使用双数组,如下所示。
当 A
的第二个构造函数是显式时会出现编译错误,但当 A
的第二个构造函数不是显式时一切正常。我假设应该从 const double*
转换为 const A
但我不确定。然后我调试代码,我看到只有A
的第一个构造函数被调用了。
那么,如果第二个构造函数是显式的还是不是,为什么这很重要?
class A {
public:
friend class B;
private:
A(double v1, double v2): _x{v1, v2}{}
explicit A(const double *arr2): _x{*arr2, *(arr2+1)}{}
double _x[2];
};
class B {
private:
A _b1, _b2;
static double foo(const A &first, const A &second){
return first._x[0]*second._x[1];
}
public:
B(): _b1(2.1, 2.2), _b2(1.2, 1.1){}
B(double List[2][2]): _b1(List[0][0],List[0][1]), _b2(List[1][0], List[1][1])
{}
void Problem( const double* bArr, double* result) const{
double goesTo=thisfunc();
*result =foo(bArr, _b1)/goesTo; //this is where Clion states a possible problem
}
double thisfunc() const{
return foo(_b1, _b2);
}
};
int main() {
double initArray[][2]={{2,1},{1,1}};
B M(initArray);
return 0;
}
您似乎正在将指针 bArr
传递给引用参数。您可能想先取消引用指针:
*result =foo(*bArr, _b1)/goesTo;
此外,我 99% 确定这正是错误消息所述的内容。
回答你的问题。没有从指针到引用的隐式转换(转换)。您必须显式使用解引用运算符 - prefixed*
。复制构造函数不是转换运算符,转换运算符也不是构造函数。
class T
中的转换运算符将 T
转换为其他类型。复制构造函数将 T
的一个实例复制到 T
的另一个实例。带有其他类型的一个参数的普通构造函数可以看作是将所述其他类型转换为类型 T
.
的实例
编辑: 正如 Pete Becker 所指出的,这并不能解决问题,因为 explicit A(const double *arr2)
被标记为显式,因此禁止编译器执行一个隐式转换这是允许的。
所以正确的解决方案是直接从 bArr
创建 A
或将其标记为隐式
问题中的代码比较复杂,但是问题很简单
void f(const A&);
double data[] = { 1.0, 2.0 };
f(data); // error
当A(const double*)
被标记为explicit
时,不允许编译器使用它来隐式地将data
转换为A
类型的对象。为了使用该构造函数,代码必须进行显式转换:
f(static_cast<A>(data));
毕竟,这就是 explicit
的意思。
我的 Clion IDE 告诉我,当我将 const double*
类型传输到具有参数 const A
且定义了 A
的函数时可能会出现问题使用双数组,如下所示。
当 A
的第二个构造函数是显式时会出现编译错误,但当 A
的第二个构造函数不是显式时一切正常。我假设应该从 const double*
转换为 const A
但我不确定。然后我调试代码,我看到只有A
的第一个构造函数被调用了。
那么,如果第二个构造函数是显式的还是不是,为什么这很重要?
class A {
public:
friend class B;
private:
A(double v1, double v2): _x{v1, v2}{}
explicit A(const double *arr2): _x{*arr2, *(arr2+1)}{}
double _x[2];
};
class B {
private:
A _b1, _b2;
static double foo(const A &first, const A &second){
return first._x[0]*second._x[1];
}
public:
B(): _b1(2.1, 2.2), _b2(1.2, 1.1){}
B(double List[2][2]): _b1(List[0][0],List[0][1]), _b2(List[1][0], List[1][1])
{}
void Problem( const double* bArr, double* result) const{
double goesTo=thisfunc();
*result =foo(bArr, _b1)/goesTo; //this is where Clion states a possible problem
}
double thisfunc() const{
return foo(_b1, _b2);
}
};
int main() {
double initArray[][2]={{2,1},{1,1}};
B M(initArray);
return 0;
}
您似乎正在将指针 bArr
传递给引用参数。您可能想先取消引用指针:
*result =foo(*bArr, _b1)/goesTo;
此外,我 99% 确定这正是错误消息所述的内容。
回答你的问题。没有从指针到引用的隐式转换(转换)。您必须显式使用解引用运算符 - prefixed*
。复制构造函数不是转换运算符,转换运算符也不是构造函数。
class T
中的转换运算符将 T
转换为其他类型。复制构造函数将 T
的一个实例复制到 T
的另一个实例。带有其他类型的一个参数的普通构造函数可以看作是将所述其他类型转换为类型 T
.
编辑: 正如 Pete Becker 所指出的,这并不能解决问题,因为 explicit A(const double *arr2)
被标记为显式,因此禁止编译器执行一个隐式转换这是允许的。
所以正确的解决方案是直接从 bArr
创建 A
或将其标记为隐式
问题中的代码比较复杂,但是问题很简单
void f(const A&);
double data[] = { 1.0, 2.0 };
f(data); // error
当A(const double*)
被标记为explicit
时,不允许编译器使用它来隐式地将data
转换为A
类型的对象。为了使用该构造函数,代码必须进行显式转换:
f(static_cast<A>(data));
毕竟,这就是 explicit
的意思。