0

我对继承的概念很陌生,对 C++ 也很陌生,所以我的问题可能真的很愚蠢......

class A {
    public :
        A() {}
        A(string name) {name_ = name}

    private :
        string name_;
}

class B : public A {
    public :
        B() {}
        B(string name, int number) {
            name_ = name;
            number_ = number;
        }

    private :
        string name;
        int number;
}

class C {
    public :
        C() {}
        void addClass(int id, A* a) {
            map[id] = a;
        }

    private :
        Hash_Map<int, A*> map;
}

void main() {
    C* c = new C();
    for (int i = 0; i < 10; i++) {
        B* b = new B("randomName", 50);
        c->addClass(i, b); //1st problem
        delete b;            //2nd problem
    }

}

第一个问题:“c”中的“map”不应该保留“B”类的属性“number”吗?我知道我把 A* 放在参数中,但是如果我有几个从 A 派生的类,我应该怎么做?

第二个问题:当我删除“b”时,“map”中的所有属性似乎都获得了随机值。我猜问题是我需要将“b”复制到一个新对象中,但是如果我有“A*”作为我的 addClass() 参数,我该怎么做呢?我的指针 b 似乎被转换成它的父类

编辑:不得不更改我忘记的代码中的几件事......

4

1 回答 1

1

一堆问题:

1)类声明中没有初始化成员!(您的编辑解决了这个问题)

class B : public A {
public :
    B() : name("A"), number(0) {} // initialize in constructor. that's what they are for!

private :
    string name;
    int number;

}

(对 A 的声明也重复一遍)

2)您在A地图中存储指向(作为参数传递给addClass)的指针的副本,而不是实际的对象。因此,您的地图包含: 100 -> 指向b

然后删除 b 指向的任何内容。你认为map[100]现在包含什么?指向垃圾的指针!所以,不要删除外面的指针!让C来处理。

3)(我之前的答案有一个明显的错误,有人投票赞成。所以,我会保留前面的部分并指出我的错误)除非你需要,否则不要使用指针。为自己节省一些工作。去弹吉他或阅读 Herb Sutter 的一些文章吧!

void main() {
   // don't use pointers and require that you delete them (unless you need to)
   B b; // default constructor is called automatically. it is destroyed for you, by the compiler
        // at the end of its scope (in this case, closing brace of main() )

   C c; 
   c.addClass(100, b);
}

让我们也修复C。我们能摆脱那些讨厌的指针吗?

class C {
public :
    C() {}
    void addClass(const int id, const A a) { // use const, its a good habit!
        map[id] = a;
    }

private :
    Hash_Map<int id, A a> map;

}

现在,这有什么问题?不仅仅是额外的副本;当您通过b值作为参数传递给 addClass 时,编译器将复制b` 的数据A部分b! So, we lost(并覆盖)!

因此,我们绝对必须使用指针(引用是危险的,因为它们在范围退出时被删除)。

重要的是你让 C 拥有删除。

所以你的代码现在看起来像:

class C {
public :
    C() {}
    ~C() {
       for(pair<int, A*>& p : map) // C++11 syntax, yay!
          delete p.second; // here's where you clean up. not in main.

    }
    void addClass(const int id, const A* a) {
        map[id] = a;
    }

private :
    Hash_Map<int, A*> map;
}

void main() {
    B* b = new B(); // back to square 1!
    C c;
    c.addClass(100, &b);
} // no memory leaks

但我讨厌你说的删除..不要害怕,我们有shared_ptr!

#include <memory>
using namespace std;
typedef shared_ptr<A> Aptr;

class C {
public :
    C() {}
    ~C() {
        cout << "Drinking a beer coz i use shared_ptr";     
    }
    void addClass(const int id, Aptr& a) {
        map[id] = a;
    }

private :
    Hash_Map<int, Aptr> map;
}

void main() {
    Aptr b(new B());
    C c;
    c.addClass(100, b);
} // still no memory leaks

希望有帮助。

于 2013-10-17T03:24:48.440 回答