简体   繁体   English

如何初始化成员变量

[英]How to Initialize Member Variables

Probably an easy question for someone out there, but what am I doing wrong in the below example? 对于外面的人来说,这可能是一个简单的问题,但是在下面的示例中我做错了什么? I'm trying to build a global class which contains instantiations of other classes within... I think where I'm going wrong boils down to the below example. 我正在尝试构建一个全局类,其中包含其他类的实例化...我认为我要去哪里出错可以归结为以下示例。 Getting a seg fault, as if *b is never created. 遇到段错误,就好像从未创建* b一样。 Thanks in advance!! 提前致谢!!

#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();
}
A() {
    B *b = new B;
}

B * b;

In the constructor you're declaring a new local variable that gets assigned the address of the freshly allocated B , and then forgotten! 在构造函数中,您要声明一个新的局部变量 ,该局部变量被分配了新分配的B的地址,然后被遗忘了!

The instance field b is never assigned to because it is shadowed by the local variable of the same name in the constructor. 实例字段b永远不会分配给它,因为它在构造函数中被相同名称的局部变量所遮盖。

You probably mean to do 你可能想做

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

should be 应该

A()
{
    b = new B;
}

In your version there a variable called b in the A constructor. 在您的版本中,A构造函数中有一个名为b的变量。 This variable hides the A class member also called b (which was obviously the one you wanted to use). 此变量隐藏也称为b的A类成员(显然是您要使用的成员)。

In the cosntructor A::A() you don't initilize the A::b member, but a local variable instead. 在cosntructor A::A()您不初始化A::b成员,而是初始化一个局部变量。 Try doing: 尝试做:

A() {
     b = new B;
}

or better: 或更好:

A():b(new B) {}

And even better, don't use the raw pointer at all. 甚至更好的是,根本不使用原始指针。

B *b = new B;

Creates a local variable named b which shadows the class member b . 创建一个名为b的局部变量,该变量遮盖了类成员b You need to initialize the class member, and you should do it in an initialization list. 您需要初始化类成员,并且应该在初始化列表中进行。

A() : b(new B) {}

Your next step is to fix the memory leak caused by never calling delete on the pointers you dynamically allocate, but since this is a learning exercise it's probably not terribly important (yet). 下一步是修复由于从未在动态分配的指针上调用delete而导致的内存泄漏,但是由于这是一项学习练习,因此可能还不是很重要。

Although quite a few people have pointed out one way of fixing the problem you're seeing, none seems (to me, anyway) to be giving advice about how to really make the code better. 尽管有很多人指出了解决您所遇到的问题的一种方法,但似乎(无论如何对我来说)似乎都没有提供有关如何真正使代码变得更好的建议。

Your definition of B is what's called a quasi-class . 您对B定义是所谓的quasi-class To make a long story short, your B can be simplified a lot without losing anything: 长话短说,您的B可以大大简化而不会丢失任何东西:

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

Everything else you've done (get/set, destructor) are accomplishing absolutely nothing. 您已完成的所有其他操作(获取/设置,析构函数)完全没有完成。 Your A class not only accomplishes just about as little, but does it even more poorly. 您的A类不仅完成了几乎一样的功课,而且做得更差。 Others have already pointed out the problem with A 's constructor defining a local B object, and then leaking that object. 其他人已经指出了A的构造函数定义一个本地B对象,然后泄漏该对象的问题。 None (that I've seen yet, anyway) has pointed out that even when you fix that, your definition of A will leak the B object anyway, because even though it creates a B object as part of creating an A object, it does not destroy the B object when the A object that contains it is destroyed. 无(我见过的,反正)曾指出,即使你解决这个问题,你定义A将泄漏B反正对象,因为即使它会创建一个B对象创建的一部分A对象,它销毁包含它的A对象时, 不要销毁B对象。

I don't see any reason for your A class to dynamically allocate the B object at all (or, when you get down to it, to even exist). 我完全没有理由让您的A类动态分配B对象(或者当您开始使用它时,甚至不存在)。 I'd define A more like this: 我将定义A更像这样:

class A { 
     B b;
public:
     void print() { std::cout << b.b << "\n";
};

It would be better, however, if a B object knew how to insert itself into a stream -- and if it used the normal syntax for that as well: 但是,如果B对象知道如何将自己插入流中,并且它也使用普通语法,那会更好:

std::ostream &operator<<(std::ostream &os, B const &b) { 
    return os << b.b;
}

With this in place, your A class adds nothing at all, so your entire program becomes something like this: 完成此操作后,您的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;
}

Great tips guys, even though in retrospect I obfuscated my issue with naming the int variable b (should've been anything but b!!). 很好的提示,即使回想起来,我还是用int变量b的名字来混淆我的问题(应该是b以外的东西!)。 That said, you guys "pointed" me in the direction to initialization lists, destructors, and ultimately to the topic of composition. 就是说,你们将我“指向”了初始化列表,析构函数,最后是合成主题。 Many thanks How to implement class composition in C++? 非常感谢如何在C ++中实现类组合?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM