首页 > 解决方案 > 是否将构造函数的参数作为类的实例传递?

问题描述

我遇到了这种情况(简化)
这编译时没有任何关于它似乎如何将给定参数转换为类 A 的构造函数中类 B 的实例的警告

class B{
    public:
        B(int _x) { }
        virtual ~B() { }
};

class A{
    public:
        A(const B& source) { }
        virtual ~A() { }
};

int main(){
    new A(1);
    return 0;
}

1. 这被认为是好的做法吗?

当被要求提供实例/常量引用时,我还没有看到 C++ 中提供构造函数参数的任何代码。是潜规则吗?

2. 在没有警告和警告的情况下,这在多大程度上是可能/允许的?

const当函数原型要求(不是)引用 时,这不起作用。

3. 编译器什么时候认为这比重载函数更好?

编译以下示例:

class B
{
    public:
        B(double _x = 0, double _y = 0) { }
        virtual ~B() { }
};

class A
{
    public:
        A(const B& source, int z = 0) {cout << "B class constructor";}
        A(double _x, double _y){cout << "primitive types";}
        virtual ~A() { }
};

int main()
{
    new A(1, 1);
    return 0;
}

给出警告(使用某些编译器选项):

warning: ISO C++ says that these are ambiguous, even though the worst conversion for the first is better than the worst conversion for the second:
note: candidate 1: A::A(double, double)
note: candidate 2: A::A(const B&, int)

(我知道编译器与 int->double 冲突)

但是当int z = 0从构造​​函数中删除参数时(const B&, int),警告会消失(并且仍然打印“ primitive types”)
,这在我看来更加模棱两可。

歧义是如何决定的?

标签: c++constructor

解决方案


  1. 这被认为是好的做法吗?

当被要求提供实例/常量引用时,我还没有看到 C++ 中提供构造函数参数的任何代码。是潜规则吗?

'给出构造函数的参数'是没有意义的。这里发生的是一个const B对象是double通过您为此目的提供的构造函数从 a 构造的。没有比这更神秘的了。它实际上是一个简单的类型转换操作,如果在传递参数或返回值时可用,C++ 编译器将始终考虑单步类型转换。

  1. 在没有警告和警告的情况下,这在多大程度上是可能/允许的?

在某种程度上,它可以在一个单一的步骤中没有歧义。

当函数原型要求(非 const)引用时,这不起作用。

这是因为编译器不会按照 C++ 的规则构造非常量临时对象。

  1. 编译器何时认为这比重载函数更好?...在我的选择中更加模棱两可

它不是。

歧义如何解决?

没有歧义需要解决。C++ 中没有规则说它应该尝试用const B两个或多个参数构造单个对象。


推荐阅读