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

How to wrap another class (c++)

本文关键字:另一个 c++ 包装 何包装      更新时间:2023-10-16

在用其他面向对象语言编程多年后,我正在努力学习c++。

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

例如,用下面的…

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成员变量有关,但我无法找出正确的方法来完成这一点。

main.cpp

#include "foo.cpp"
#include <iostream>
int main()
{
    Foo foo(42);
    std::cout << foo.get_barx() << std::endl; 
    return 0;
}

这里你应该包含一个头文件(例如,将"foo.cpp"重命名为"foo.h")。一般来说,头文件提供声明,而源文件(例如,.cpp文件)提供定义/实现。

Bar.cpp(同样应该是标题)

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(同样应该是头文件)

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

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

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