0

对于那里的人来说可能是一个简单的问题,但是在下面的示例中我做错了什么?我正在尝试构建一个全局类,其中包含其他类的实例化......我认为我出错的地方归结为下面的示例。出现 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();
}
4

6 回答 6

3
A() {
    B *b = new B;
}

B * b;

在构造函数中,您声明了一个新的局部变量,该变量被分配了新分配的地址B,然后被遗忘了!

实例字段b永远不会被分配,因为它被构造函数中同名的局部变量所遮蔽。

你可能的意思是

A() {
    b = new B;
}
于 2012-10-28T22:42:32.617 回答
1
A()
{
    B *b = new B;
}

应该

A()
{
    b = new B;
}

在您的版本中,A 构造函数中有一个名为 b 的变量。这个变量隐藏了也称为 b 的 A 类成员(这显然是您想要使用的那个)。

于 2012-10-28T22:42:04.673 回答
1

在 cosntructorA::A()中,您不会初始化A::b成员,而是初始化局部变量。尝试做:

A() {
     b = new B;
}

或更好:

A():b(new B) {}

更好的是,根本不要使用原始指针。

于 2012-10-28T22:43:13.853 回答
1

尽管很多人已经指出了解决您所看到的问题的一种方法,但似乎(对我来说,无论如何)都没有就如何真正使代码变得更好提供建议。

您的定义B是所谓的 a quasi-class。长话短说,您B可以在不丢失任何内容的情况下进行很多简化:

struct B { 
    int b;
    B() : b(99) {}
};

你所做的一切(get/set,析构函数)都没有完成任何事情。你的A班级不仅完成得差不多,而且做得更差。其他人已经指出了A' 的构造函数定义一个本地B对象,然后泄漏该对象的问题。没有(无论如何我已经看到)指出,即使你修复了这个问题,你的定义仍然A会泄漏B对象,因为即使它创建一个B对象作为创建对象的一部分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;
}
于 2012-10-28T23:23:30.427 回答
1
B *b = new B;

创建一个名为b遮蔽类成员的局部变量b。您需要初始化类成员,并且应该在初始化列表中进行。

A() : b(new B) {}

您的下一步是修复由于从不调用delete您动态分配的指针而导致的内存泄漏,但由于这是一个学习练习,它可能不是非常重要(还)。

于 2012-10-28T22:43:32.043 回答
0

很棒的提示,尽管回想起来我在命名 int 变量 b 时混淆了我的问题(应该是 b !)。也就是说,你们向我“指出”了初始化列表、析构函数以及最终组合的主题。非常感谢如何在 C++ 中实现类组合?

于 2012-10-31T02:35:00.437 回答