如何包装另一个类(c+;+;) 我试图在其他OO语言编程之后学习C++。
我正试图为另一个类创建一个包装器类,但很难弄清楚如何正确设置它 例如,使用以下 main.cpp如何包装另一个类(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
#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();
}
};