如何声明类的对象而不将参数传递给它的构造函数?

时间:2014-07-15 10:40:36

标签: c++

我有一个类,其构造函数有一个参数。现在我必须声明A类对象。但我需要稍后调用构造函数。但如果我这样做,我就会收到错误。

e.g。

class A{
        public:
        int a;
        A(int x){
                a=x;
        }
};
int main(){
        A a;
        a=A(3);
}

错误

temp.cpp: In function ‘int main()’:
temp.cpp:10:4: error: no matching function for call to ‘A::A()’
temp.cpp:10:4: note: candidates are:
temp.cpp:5:2: note: A::A(int)
temp.cpp:5:2: note:   candidate expects 1 argument, 0 provided
temp.cpp:3:7: note: A::A(const A&)
temp.cpp:3:7: note:   candidate expects 1 argument, 0 provided

5 个答案:

答案 0 :(得分:2)

带参数的构造函数的要点是确保在没有初始化的情况下不存在类的任何对象。你不能在以后调用构造函数"。您可以添加另一个构造函数,但不带参数。

答案 1 :(得分:2)

这里唯一的好办法是首先避免出现这种情况。

当您在必须创建一个初始值取决于某些条件的对象的一般顺序上有某些东西时,通常会出现这种情况,因此概念上您想要的是这个一般顺序:

if (xyz)
    A a(123);
else
    A a(456);

// code that uses A goes here

在这种情况下的问题是,在这种情况下,A超出范围之后才能使用它。解决方法通常是将此代码分为两个函数,因此您最终会得到类似的结果:

if (xyz)
    code_that_uses_A(123);
else
    code_that_uses_A(456);

虽然我当然更愿意避免它,但是可以的另一种可能性是:一个包装器对象,它跟踪它所包含的对象是否已被初始化。例如,它可以包含指向实际对象的指针。这被初始化为空指针。初始化它包含的对象时,将分配一个包含的对象。根据您的需要,尝试重新初始化容器对象可能会抛出,或者只是为包含的对象分配一个新值。

在这两者中,前者几乎总是优选的。它倾向于清理代码并为每个单独的代码提供单一,明确的责任。后者可以工作,但通常需要相当多的工作才能使包装器对象呈现干净的界面。虽然我通常认为这是一个较小的问题,但这样的包装器通常会增加使用包装对象的大量开销。

答案 2 :(得分:0)

每当定义一个对象时。构造函数自动调用。您可能拥有以下内容:

class A{
  int a;
 public:
  A(int x = 0){
    a=x;
  }
  A(const A&arg) {a = arg.a;}
  A& operator =(const A&arg) {a = arg.a;return *this;}
};
int main(){
  A a;
  a=A(3);
  return 0;
}

构造函数也可能有默认参数,因此A a;实际上可能实现为类似于对构造函数A(0)的调用。请参阅Default parameters with C++ constructors

答案 3 :(得分:0)

这里的问题是你已经为A类定义了一个构造函数,它以int作为参数。 由于您已经定义了自己的构造函数,因此编译器不会为您的类定义默认构造函数。

A(int x)
{
        a=x;
}

致电时:

A a;

这将为A类寻找一个不带任何参数的构造函数。但那不存在。因此编译错误即将到来。

答案 4 :(得分:-1)

您应该初始化类的任何实例。没有办法让一个"虚拟"变量没有明确定义的状态,除非你的类有一个没有参数的构造函数。

或者,添加一个没有参数的构造函数。

请注意,a = A(3)中的分配会在a上调用分配运算符。