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

时间:2015-09-29 00:22:21

标签: c++ class c++11 wrapper

我正在尝试用其他OO语言编程多年后学习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成员变量,但我无法弄清楚实现此目的的正确方法。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:0)

You need to use initialization lists to construct class members at construction time. The body of the constructor gets called after all members have been constructed. If you don't explicitly call a non-default constructor then the compiler will insert a call to the default constructor for you. For example, your Foo class could look like:

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