C++ 动态分配属性与继承

C++ 动态分配属性与继承,c++,inheritance,dynamic-memory-allocation,C++,Inheritance,Dynamic Memory Allocation,我写了两篇课文。在基本类中,我有属性age,它是动态分配的。我试着在课堂上使用它。代码执行,但它给我输出: mammal create dog create how 2 dog delete mammal delete munmap_chunk(): invalid pointer Aborted (core dumped) 我的代码有什么问题,我应该如何将其更改为指针没有问题 这是我的密码: #include <iostream> class Mammal {

我写了两篇课文。在基本类中,我有属性age,它是动态分配的。我试着在课堂上使用它。代码执行,但它给我输出:

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 getAge();
无效设置(内部管理);
私人:
国际*年龄;
};
哺乳动物:哺乳动物(内部)
{
整数*年龄=新整数;
年龄=&nAge;

std::cout错误在这两个函数中:

Mammal::Mammal(int nAge)
{
    int* age = new int;
    age = &nAge;
    std::cout<<"mammal create \n";
}

void Mammal::setAge(int nAge)
{
    age = &nAge;
}

这将把分配的变量分配给
nAge
的值,并正确分配成员。

在构造函数中有这两行

int *age = new int;
age = &nAge;
它们导致三个问题:

首先,定义一个完全不同且唯一的变量名
age
,它与同名的成员变量完全分离

其次,您将使用指向
nAge
的指针覆盖指针。这意味着您将丢失已分配的原始指针,并且内存泄漏

第三个问题是使
age
指向局部变量
nAge
。当函数返回时,变量
nAge
一旦超出范围,它的生命就会结束。指向该变量的任何指针都将变为无效

要解决您的问题,最简单的解决方案是同时初始化和分配:

age = new int(nAge);
或者,如果您需要分两步进行:

age = new int;
*age = nAge;   // Copy the value of nAge into the memory pointed to by age
如注释中所述,这仍然不是一个好的解决方案,因为如果您使用复制赋值运算符的默认复制构造函数(只复制指针本身,而不分配新内存),则复制对象将导致问题


至于继承,还有两个问题……第一个问题是
哺乳动物
没有默认构造函数,而子类
依赖于默认构造函数。这里简单的解决方法是创建
哺乳动物
默认构造函数。您还可以让
构造函数使用参数化的
Mammal
构造函数通过
构造函数初始值设定项列表:

Dog::Dog()
    : Mammal(0)  // Initializes with a default age of zero
{
}
然后
哺乳动物
析构函数需要是
虚拟的
,否则当
对象被析构函数时,它将不会被调用,从而导致内存泄漏


要继续执行
setAge
函数,它不会检查
age
的内存是否已分配。它还包含上面列出的构造函数的第三个问题,即它使
age
指向局部变量
nAge
,该变量将在函数返回时消失。

现在它工作了,w没有错误

#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;
}
#包括
哺乳类
{
公众:
哺乳动物;
虚拟哺乳动物();
哺乳动物(哺乳动物&);
int getAge();
无效设置(内部管理);
私人:
国际*年龄;
};
哺乳动物:哺乳动物(内部)
{
年龄=新整数(nAge);

std::可能不是您现在面临的问题,但是请注意,您的类现在的方式是错误的,并且在以某些方式使用时会导致未定义的行为,因为它不遵循发布的代码,与您声明的错误不同:test.cpp(55):错误C2512:“哺乳动物”:没有合适的默认构造函数可用。无论您在何处拥有age=&nAge,都应替换为*age=nAge。如果没有明确的理由,age
不应是指针。它应该只是一个
int
,或者它必须是一个拥有者指针
std::unique\u ptr
。是否可以提示me除了动态分配之外,什么时候是使用它的好理由,或者当动态内存分配不是比我详细得多的好理由时!请编辑您的问题和/或对您所指的答案进行评论,而不是写非答案。
#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;
}