Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何包装另一个类(c+;+;) 我试图在其他OO语言编程之后学习C++。_C++_Class_C++11_Wrapper - Fatal编程技术网

如何包装另一个类(c+;+;) 我试图在其他OO语言编程之后学习C++。

如何包装另一个类(c+;+;) 我试图在其他OO语言编程之后学习C++。,c++,class,c++11,wrapper,C++,Class,C++11,Wrapper,我正试图为另一个类创建一个包装器类,但很难弄清楚如何正确设置它 例如,使用以下 main.cpp #include "foo.cpp" #include <iostream> int main() { Foo foo(42); std::cout << foo.get_barx() << std::endl; return 0; } bar.cpp class Bar { public: int m_x; // I se

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

例如,使用以下

main.cpp

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

int main() {
  Foo foo(42);
  std::cout << foo.get_barx() << std::endl; 
  return 0;
}
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
member变量有关,但我不知道实现这一点的正确方法是什么。

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

class Foo {
public:
    Foo(int y) : m_bar(y*2) {}
    ...
private:
    Bar m_bar;
}
main.cpp foo.cpp(同样,这应该是一个标题)
Bar m_Bar(y*2)只创建一个局部变量。使用赋值。顺便说一句,文件扩展名“.cpp”按非常强的约定表示一个实现文件,一个用于单独编译的文件。头文件的扩展名通常为“.h”或“.hpp”。此外,在每个头文件的顶部添加一次
#pragma
,或者使用老式的include-guard(仔细阅读)。啊哈。好啊将
Bar m_Bar(y*2)
更改为
m_Bar=Bar(y*2)
会得到我期望的结果(谢谢@cheers-sandhth.-Alf),但我想我仍然不明白为什么
Bar m_Bar声明需要一个默认构造函数。也许这正是我需要学会适应的东西?@JonGarvin我补充了一个答案,这个答案应该能让我更清楚地了解默认构造函数和初始化。
class Foo {
public:
    Foo(int y) : m_bar(y*2) {}
    ...
private:
    Bar m_bar;
}
#include "foo.cpp"
#include <iostream>

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

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