我已经写了两节课。在基础课中,我有属性age,它是动态分配的。我尝试在Dog类中使用它。该代码执行了,但是给了我输出:
mammal create
dog create
how
2
dog delete
mammal delete
munmap_chunk(): invalid pointer
Aborted (core dumped)
我的代码有什么问题,如何将其更改为指针没有问题。
这是我的代码:
#include <iostream>
class Mammal
{
public:
Mammal(int nAge);
~Mammal();
int getAge();
void setAge(int nAge);
private:
int *age;
};
Mammal::Mammal(int nAge)
{
int *age = new int;
age = &nAge;
std::cout<<"mammal create \n";
}
Mammal::~Mammal()
{
std::cout<<"mammal delete \n";
delete age;
}
int Mammal::getAge()
{
return *age;
}
void Mammal::setAge(int nAge)
{
age = &nAge;
}
class Dog : public Mammal
{
public:
Dog();
~Dog();
void getVoice();
};
Dog::Dog ()
{
std::cout << "dog create \n";
}
Dog::~Dog()
{
std::cout<<"dog delete \n";
}
void Dog::getVoice()
{
std::cout<<"how \n";
}
int main()
{
Dog* dog = new Dog;
dog -> getVoice();
dog -> setAge(2);
std::cout<<dog-> getAge()<<"\n";
delete dog;
}
摘要,我想了解内存分配如何与继承一起工作。
在构造函数中,您有这两行
int *age = new int;
age = &nAge;
它们导致三个问题:
首先,您定义一个完全不同且唯一的变量名称age
,该名称与相同名称的成员变量完全分开。
其次,您用指向nAge
的指针覆盖了指针。这意味着您将丢失分配的原始指针,并发生内存泄漏。
第三个问题是使age
指向local变量nAge
。当函数返回时,变量nAge
一旦超出范围,将终止其寿命。指向该变量的任何指针都将变为无效。
为了解决您的问题,最简单的解决方案是同时初始化和分配:
age = new int(nAge);
或者,如果您需要分两步进行:
age = new int;
*age = nAge; // Copy the value of nAge into the memory pointed to by age
如评论中所述,这仍然不是一个很好的解决方案,因为如果您使用copy-assignment运算符的默认copy-constructor来复制对象,则该问题只会复制指针本身,而不进行分配,这会导致问题新的内存。
关于继承,还有两个问题……首先是Mammal
没有默认的构造函数,子类Dog
依赖于此。这里简单的解决方案是使Mammal
默认构造函数。您还可以通过Dog
构造函数初始化器列表,使Mammal
构造函数使用参数化的Dog
构造函数:
Dog::Dog()
: Mammal(0) // Initializes with a default age of zero
{
}
然后,Mammal
析构函数必须为virtual
,否则当Dog
对象被析构时将不会调用它,从而导致内存泄漏。
并且继续setAge
功能不会检查age
的内存是否已分配。它还包含构造函数上面列出的第三个问题,因为它使age
指向局部变量nAge
,该局部变量在函数返回时将消失。
错误在于这两个功能:
Mammal::Mammal(int nAge)
{
int* age = new int;
age = &nAge;
std::cout<<"mammal create \n";
}
void Mammal::setAge(int nAge)
{
age = &nAge;
}
age
指针指向局部变量nAge
。该变量在作用域的末尾(在}
之后)死亡。
此外,我想您想分配给Mammal::age
,但您要在其中创建一个新变量。
您应该做的是这样:
Mammal::Mammal(int nAge)
{
age = new int;
*age = nAge;
std::cout<<"mammal create \n";
}
void Mammal::setAge(int nAge)
{
*age = nAge;
}
[这会将分配的变量分配给nAge
的值,并且也正确分配了成员。
现在可以正常使用,没有错误
#include <iostream>
class Mammal
{
public:
Mammal(int nAge);
virtual ~Mammal();
Mammal(Mammal&);
int getAge();
void setAge(int nAge);
private:
int *age;
};
Mammal::Mammal(int nAge)
{
age = new int(nAge);
std::cout<<"mammal create \n";
}
Mammal::~Mammal()
{
std::cout<<"mammal delete \n";
delete age;
}
Mammal::Mammal(Mammal& rhs)
{
age = new int;
*age = rhs.getAge();
}
int Mammal::getAge()
{
return *age;
}
void Mammal::setAge(int nAge)
{
*age = nAge;
}
class Dog : public Mammal
{
public:
Dog();
~Dog();
void getVoice();
};
Dog::Dog ():Mammal(0)
{
std::cout << "dog create \n";
}
Dog::~Dog()
{
std::cout<<"dog delete \n";
}
void Dog::getVoice()
{
std::cout<<"how \n";
}
int main()
{
Dog* dog = new Dog;
dog -> getVoice();
dog -> setAge(2);
std::cout<<dog-> getAge()<<"\n";
delete dog;
}
有人可以检查一下,如果现在一切都还好吗?