在类中实例化一个类

Jos*_*ury 0 c++ class

我正在尝试在类中实例化一个类,以便外部类包含内部类.

这是我的代码:

#include <iostream>
#include <string>

class Inner {
    private: 
        std::string message;

    public:
        Inner(std::string m);
        void print() const;
};

Inner::Inner(std::string m) {
    message = m;
}

void Inner::print() const {
    std::cout << message << std::endl;
    std::cout << message << std::endl;
}

class Outer {
    private:
        std::string message;
        Inner in;

    public:
        Outer(std::string m);
        void print() const;
};

Outer::Outer(std::string m) {
    message = m;
}

void Outer::print() const {
    std::cout << message << std::endl;
}

int main() {
    Outer out("Hello world.");
    out.print();

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

"Inner in",是我在外部包含内部的尝试,但是,当我编译时,我得到一个错误,即没有匹配函数来调用Inner :: Inner().我做错了什么?

谢谢.

sbi*_*sbi 6

您需要使用初始化列表来初始化类成员:

Inner::Inner(const std::string& m)
  : message(m)
{
}

Outer::Outer(const std::string& m)
  : in(m)
{
}
Run Code Online (Sandbox Code Playgroud)

(请注意,我按const引用传递了字符串,这比通过值传递它们更好.请参阅此答案以了解如何传递函数参数.)

这样,您可以准确指定应为类成员调用哪些构造函数.

如果未指定构造函数,则将隐式调用默认构造函数.稍后分配给对象将调用赋值运算符并覆盖默认构造函数初始化对象的任何内容.那是最好的浪费表现.
由于我们Inner没有默认构造函数(声明任何构造函数阻止编译器自己定义默认构造函数),因此无法调用它,因此您需要指定显式获取字符串的构造函数.


编辑:请注意,如果您有多个类成员,则它们都以这种方式初始化,用逗号分隔:

Outer::Outer(const std::string& m) : in1(m), in2(m), in3() {}
Run Code Online (Sandbox Code Playgroud)

请注意,类成员的初始化顺序取决于它们在类定义中的声明顺序,而不是它们在初始化列表中出现的顺序.最好不要依赖初始化顺序,因为在类定义中更改它会在构造函数的定义中创建一个非常微妙的错误.如果您无法避免,请在类成员声明之外发表评论:

class outer {
  public:
    outer(const inner& in) 
     : in_(in), rin_(in_) // depends on proper declaration order of in_ and rin_
    {}
  private:
    inner in_;   // declaration order matters here!1
    inner& rin_; // (see constructor for details)
};
Run Code Online (Sandbox Code Playgroud)

基类构造函数以相同的方式指定,它们在类成员之前初始化,也按基类列表中的声明顺序初始化.但是,虚拟基类在所有非虚基类之前初始化.


析构函数BTW总是以构造函数的相反顺序调用.你可以依靠它.