我之前在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.
我对此代码进行了简化和条带化处理,因为我认为这与我记忆和分配的问题无关。
答案 0 :(得分: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;
}
如果它是“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)。