动态分配的属性和继承

问题描述 投票:-1回答:3

我已经写了两节课。在基础课中,我有属性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;
}

摘要,我想了解内存分配如何与继承一起工作。

c++ inheritance dynamic-memory-allocation
3个回答
3
投票

在构造函数中,您有这两行

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,该局部变量在函数返回时将消失。


2
投票

错误在于这两个功能:

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的值,并且也正确分配了成员。


-1
投票

现在可以正常使用,没有错误

#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;
}

有人可以检查一下,如果现在一切都还好吗?

© www.soinside.com 2019 - 2024. All rights reserved.