放在向量中的C ++类持有者

时间:2013-09-07 10:13:59

标签: c++ pointers vector

我之前在Java中编写了一些编程,现在我正在尝试学习c ++,但是在理解指针,深度/浅层复制,复制构造函数,赋值运算符和那些c ++特定的东西时遇到了麻烦。 它不是真正的代码本身,它更多的是它们之间的联系以及为什么/何时需要它们。

所以我试图为自己做一个简单的例子,所以我会得到它的悬念,但我无法让它工作,它一直在崩溃。

以下是代码:

class A
{
    public:
        A();
        A(B* v);
        A(const A &o);
        virtual ~A();
        void print(std::ostream &o);
        A& operator=(A& o);
        friend std::ostream &operator<<(std::ostream &stream, A p);
    protected:
    private:
        B *value;
};

void A::print(std::ostream &o)
{
    value->print(o);
}

A& A::operator=(A& o)
{
    std::cout << "Operatorn"<< std::endl;
    this->value = o.value;
}

A::A()
{
    //ctor
}
A::A(B* v)
{
    this->value = v;
    std::cout << "B konstruktor" << std::endl;
}

A::A(const A& o)
{
    std::cout << "Kopieringskonstruktor" << std::endl;
    this->value = o.value;
}

A::~A()
{
    if(value!=NULL) delete value;
    std::cout << "Deletar value" << std::endl;
}

--------------------------------------------------

class B
{
    public:
        void print(std::ostream &o);
        B();
        B(int i):value(i){}
        virtual ~B();
    protected:
    private:
        int value;
};

--------------------------------------------------

std::ostream &operator<<(std::ostream &stream, A p)
{
    p.print(stream);
    return stream;
}

int main()
{
    vector<A> vecA;
    ostream_iterator<A> it(cout);
    vecA.push_back(A(new B(5)));
    vecA.push_back(A(new B(10)));
    copy(vecA.begin(), vecA.end(),it);
    return 0;
}

修改1

一些澄清,类似的问题是我的家庭作业。我应该有一个持有人A级,其中包含值* B.并且B继承到C和D,使我能够将C类和D类放入值* B.

我对此代码进行了简化和条带化处理,因为我认为这与我记忆和分配的问题无关。

1 个答案:

答案 0 :(得分:0)

当你决定使用对象向量时,你做出了一个很好的决定:

vector<A> vecA;

应该产生干净且易于维护的代码,但由于某种原因,你开始使事情变得比必要的更复杂。让我们从覆盖operator=开始......为什么?通常默认的运算符就足够了,如果你覆盖它,你应该有充分的理由这样做。

另一个错误的决定是当你让class A成为B*类型的成员时..为什么? AB之间有什么样的关系? A是否需要存在B类型的对象?如果是,则让C引用具有自动存储持续时间的现有对象:

class C {
public:
    C(const B& bRef) : b(bRef) { }
private:
    B& b;
}

如果它是“has”/“contains”/“由”类型的关系组成,那么将具有自动存储持续时间的对象作为成员并且如果需要初始化(在您的案例B的构造函数需要int),让类C构造此对象而不是调用者:

class C {
public:
    C(int foodForB) : b(foodForB) { }
private:
    B b;
}

会产生以下变化:A(new B(5))〜&gt; A(5)并为您节省大量工作,并防止将来出现很多可能的问题。

尽可能避免在自己的ALWAYS上进行内存管理。 同样避免动态分配〜&gt;利用具有自动存储持续时间的对象(参见RAII)。