对于那里的某个人来说可能是一个简单的问题,但在下面的例子中我做错了什么?我正在尝试构建一个包含其他类实例的全局类...我认为我出错的地方归结为下面的例子。获得seg错误,就好像* b永远不会被创建一样。在此先感谢!!
#include <iostream>
using namespace std;
class A;
class B;
class B
{
public:
B()
{
b = 99;
}
~B();
int Getb() {return b; }
void Setb (int x) { b = x; }
private:
int b;
};
class A
{
public:
A()
{
B *b = new B;
}
~A();
B * b;
void Printout()
{
cout<<b->Getb()<<endl;
}
private:
};
int main()
{
A *a = new A;
a->Printout();
cin.get();
}
答案 0 :(得分:3)
A() {
B *b = new B;
}
B * b;
在构造函数中,你是声明一个新的局部变量,它被分配了新分配的B
的地址,然后被遗忘!
实例字段b
永远不会分配给它,因为它被构造函数中同名的局部变量遮蔽。
你可能意味着
A() {
b = new B;
}
答案 1 :(得分:1)
A()
{
B *b = new B;
}
应该是
A()
{
b = new B;
}
在你的版本中,A构造函数中有一个名为b的变量。此变量隐藏了也称为b的A类成员(显然是您想要使用的成员)。
答案 2 :(得分:1)
在cosntructor A::A()
中,您不会初始化A::b
成员,而是初始化本地变量。尝试做:
A() {
b = new B;
}
或更好:
A():b(new B) {}
更好的是,根本不要使用原始指针。
答案 3 :(得分:1)
B *b = new B;
创建一个名为b
的局部变量,该变量隐藏类成员b
。您需要初始化类成员,并且应该在初始化列表中执行它。
A() : b(new B) {}
下一步是修复因动态分配的指针永远不会调用delete
而导致的内存泄漏,但由于这是一个学习练习,它可能并不是非常重要(还)。
答案 4 :(得分:1)
虽然有不少人指出了解决你所看到的问题的一种方法,但似乎没有人(无论如何)给出关于如何真正改进代码的建议。
您对B
的定义是所谓的quasi-class
。长话短说,你的B
可以简化很多而不会丢失任何东西:
struct B {
int b;
B() : b(99) {}
};
你所做的其他事情(获取/设置,析构函数)完全没有任何成就。你的A
课程不仅能完成一点点,而且能力更差。其他人已经指出了A
的构造函数定义本地B
对象,然后泄漏该对象的问题。没有(我已经看过了,无论如何)已经指出,即使你修复了这个问题,你对A
的定义也会泄漏B
对象,因为即使它创建了B
} object作为创建A
对象的一部分,当包含它的B
对象被销毁时,不会销毁A
对象。
我认为你的A
类没有任何理由动态分配B
对象(或者,当你开始使用它时,甚至存在)。我更像这样定义A
:
class A {
B b;
public:
void print() { std::cout << b.b << "\n";
};
但是,如果B
对象知道如何将自身插入流中会更好 - 并且如果它也使用了正常的语法:
std::ostream &operator<<(std::ostream &os, B const &b) {
return os << b.b;
}
有了这个,你的A
课程什么都不添加,所以你的整个课程就像这样:
struct B {
int b;
B() : b(99) {}
};
std::ostream &operator<<(std::ostream &os, B const &b) {
return os << b.b;
}
int main() {
std::cout << B() << "\n";
return 0;
}
答案 5 :(得分:0)
很棒的提示家伙,即使回想起来我用命名int变量b来模糊我的问题(应该是除了b之外的任何东西)。也就是说,你们“指出”我的方向是初始化列表,析构函数,最终指向组合主题。非常感谢How to implement class composition in C++?