如何包装另一个 class (c++)

How to wrap another class (c++)

在使用其他 OO 语言编程多年后,我正在尝试学习 c++。

我正在尝试为另一个 class 创建包装器 class,但很难弄清楚如何正确设置它。

例如,使用以下...

main.cpp

#include "foo.cpp"
#include <iostream>

int main() {
  Foo foo(42);
  std::cout << foo.get_barx() << std::endl; 
  return 0;
}

foo.cpp

#include "bar.cpp"

class Foo {
  public:
    // I'm trying to declare the member variable `m_bar` here.  I
    //   don't want to be instantiating an instance of Bar yet,
    //   but I think that might be exactly what's happening.
    Bar m_bar;

    Foo(int y) {
      // Here's where I really want to instantiate an instance of Bar
      //   and assign it to m_bar.
      Bar m_bar(y*2);
    }   

    int get_barx() {
      return m_bar.getx();
    }   
};

bar.cpp

class Bar {
  public:
    int m_x;

    // I seem to need this default constructor for the declaration
    //   of `m_bar` above, but I don't think that line should be 
    //   calling any constructors.
    Bar() { m_x = 21; };

    Bar(int x) {
      m_x = x;
    }   

    int getx() {
      return m_x;
    }   
};

当我编译并 运行 这个时,我得到了 21,但我预计是 84。我很确定我做的事情从根本上是错误的,而且我很确定它有事情要做以及我如何在 Foo 中声明 m_bar 成员变量,但我无法弄清楚完成此操作的正确方法是什么。

您需要在构造时使用初始化列表来构造 class 成员。构造函数的主体在构造完所有成员后被调用。如果您没有显式调用非默认构造函数,那么编译器将为您插入对默认构造函数的调用。例如,您的 Foo class 可能如下所示:

class Foo {
public:
    Foo(int y) : m_bar(y*2) {}
    ...
private:
    Bar m_bar;
}

main.cpp

#include "foo.cpp"
#include <iostream>

int main()
{
    Foo foo(42);
    std::cout << foo.get_barx() << std::endl; 

    return 0;
}

在这里您应该包括一个 header(例如,将 "foo.cpp" 重命名为 "foo.h")。通常,header 提供声明,源代码(例如 .cpp 文件)提供 definition/implementation.

Bar.cpp(同样应该是 header)

class Bar
{
public:
    int m_x;

    // A default constructor is not required, however defining any constructor
    // prevents auto generation of the default constructor

    Bar(int x) : // This starts the initializer list section
        m_x(x)
    {
        // This is assignment not initialization
        // m_x = x;
    }   

    // See the trailing 'const', research const correctness
    int getx() const
    {
        return m_x;
    }   
};

foo.cpp(同样应该是 header)

#include "bar.cpp"

class Foo
{
public:
    // Just declaring a `Bar` data member
    Bar m_bar;

    Foo(int y) :
        m_bar(y) // Initialize `Bar` data member using the available constructor
    {
        // First, this declares a new `Bar` instance which is different than
        // the class member, regardless of the fact they are named the same
        // Bar m_bar(y*2);

        // Furthermore, even if you did the following it is assignment not initialization
        // m_bar = Bar(y*2);

        // Since initialization already occurred before this point an error
        // will result if the `Bar` data member isn't instantiated via the
        // only available constructor, since there isn't a default constructor as
        // explained above
    }   

    // Same comment about const correctness
    int get_barx() const
    {
        return m_bar.getx();
    }   
};