0

我之前一直在用 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

一些澄清,与此类似的问题是我的家庭作业。我应该有一个包含值 *B 的持有者类 A。B 继承给 C 和 D,使我能够将 C 和 D 类都放入值 *B。

我简化并从中删除了代码,因为我认为它与我在内存和分配方面遇到的问题无关。

4

1 回答 1

0

当您决定使用对象向量时,您做出了一个正确的决定:

vector<A> vecA;

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

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

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

如果它是“具有”/“包含”/“由”类型的关系,则将具有自动存储持续时间的对象作为成员可能会更合理,以防它需要被初始化(在你的情况下B' s 构造函数需要int),让类C构造这个对象而不是调用者:

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

这将产生以下更改:A(new B(5))〜>A(5)并为您节省大量工作并防止将来出现很多可能的问题。

尽可能避免自己进行内存管理。同样避免动态分配 ~> 而是利用具有自动存储持续时间的对象(请参阅RAII)。

于 2013-09-07T10:37:42.727 回答