本文介绍了在类中实例化类的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在类中实例化一个类,以便外部类包含内部类。

I'm trying to instantiate a class within a class, so that the outer class contains the inner 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;
}

Inner in是我尝试将inner包含在outer中,然而,当我编译,我得到一个错误,没有匹配的函数调用Inner :: Inner()。
我做错了什么?

"Inner in", is my attempt at containing the inner within the outer, however, when I compile, i get an error that there is no matching function for call to Inner::Inner().What have I done wrong?

谢谢。

推荐答案

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

You need to use initialization lists to initialize class members:

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

Outer::Outer(const std::string& m)
  : in(m)
{
}

字符串每 const 引用,这比按值传递它们更好。参见

(Note that I passed the strings per const reference, which is better than passing them by value. See this answer for how to pass function arguments.)

通过这种方式,您可以精确地指定应为类成员调用哪些构造函数。

This way you can specify exactly which constructors should be called for class members.

如果不指定构造函数,默认的将被隐式调用。稍后分配给对象将调用赋值运算符并覆盖将对象初始化的默认构造函数。

因为我们的 Inner 没有默认构造函数(声明任何构造函数阻止编译器自己定义一个默认的构造函数),因此无法被调用,因此您 需要 指定显式地使用字符串的构造函数。

If you don't specify a constructor, the default one will be called implicitly. Assigning to the object later will then invoke the assignment operator and override whatever the default constructor initialized the object to. That's wasting performance at best.
Since our Inner doesn't have a default constructor (declaring any constructor prevents the compiler from defining a default constructor by itself), it cannot be called, so you need to specify the constructor taking a string explicitly.

编辑:请注意,如果您有多个课程成员,以逗号分隔:

Note that, if you have more than one class member, they are all initialized that way, separated by commas:

Outer::Outer(const std::string& m) : in1(m), in2(m), in3() {}

请注意类成员的初始化由它们在类定义 中的声明顺序确定,而不是按照它们在初始化列表中出现的顺序。最好不要依赖初始化顺序,因为在类定义中更改会在构造函数的定义中创建一个非常微妙的错误。如果你不能避免这种情况,除了类成员声明之外还要注释:

Note that the order of initialization of class members is determined by their declaration order within the class definition, not by the order they appear in the initialization list. It's best to not to rely on initialization order, since changing that in the class definition would then create a very subtle bug in the constructor's definition. If you can't avoid that, put a comment besides the class members declaration:

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)
};






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


Base class constructors are specified the same way, and they are initialized before class members, also in order of declaration in the base class list. Virtual base classes, however, are initialized before all non-virtual base classes.

Destructors,BTW总是以构造函数的相反顺序调用。你可以信赖。

Destructors, BTW, are always called in the reverse order of constructors. You can rely on that.

这篇关于在类中实例化类的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!