1
class Monitor {
public:
    Monitor(string someData);
    Person person_;
}

class Person {
public:
    Person(string personId);
}

Person 没有默认构造函数。它有一个参数构造函数。我只能Monitor 构造函数中初始化它。我来自java,其中声明只是指针,因此您在声明时不需要初始化新实例。

没有默认构造函数的类成员的最佳实践是什么?我应该添加默认构造函数(缺点 - 没有用)还是使用指针。

4

1 回答 1

7

是的,你可以,而且你总是应该通过构造函数初始化列表

class Monitor
{
    Person p; 
    bool   state;
    const  int n;
    double & d;

    Monitor(std::string const & pname, double & dbl)
    : p(pname)
    , state(false)
    , n(some_other_function(p, state))
    , d(dbl)
    {
         // constructor body should be as short as possible
    }

    // ...

};

如您所见,初始化不仅仅是一个噱头;相反,它是 C++ 类型系统的一个深刻必要性:有很多变量必须初始化且不能赋值,例如常量和引用,还有没有默认构造函数的用户定义类型。(即使有一个默认的构造函数,你也需要一个赋值操作符,而且在任何情况下构造一些你不想稍后覆盖它的东西仍然是浪费的。)

还要注意类成分的构造顺序:当您创建类的新实例时,首先构造成员对象,按照它们在类定义中声明的顺序,但按照初始化列表。构造所有成员后,构造函数的主体运行。

实际上,甚至在成员对象之前还构造了另一件事:基础子对象。自然地,它们的初始化器也出现在初始化器列表中:

struct Foo { Foo(int, bool);               /* ... */ };
struct Bar { Bar(std::string const &, int) /* ... */ };

class Monitor : public Foo, private Bar
{
    Person p;

    Monitor(std::string const & pname, int a, int b)
    : Foo(a, a == b)
    , Bar(pname, b)
    , p(pname)
    {
        // constructor body
    }

    // ...
};

强烈建议(尽管不强制)在构造函数初始化器列表中按照它们的执行顺序编写初始化器!

于 2012-09-18T08:33:52.753 回答