英文:
C++ Base class member creation via derived class
问题
I'm having difficulties understanding the following code:
class Base{
Base(){/* do stuff */};
};
class Deriv: public Base{
Deriv(){/* do stuff */};
};
// I have a problem understanding the purpose of the next line
Base &foo = *(new Deriv());
英文:
I'm having difficulties understanding the following code:
class Base{
Base(){/* do stuff */};
};
class Deriv: public Base{
Deriv(){/* do stuff */};
};
// I have a problem understanding the purpose of the next line
Base &foo = *(new Deriv());
答案1
得分: 1
First, you need to be familiar with Polymorphism, references, dereferencing, and temporary object behavior.
- 每个某个类的对象可以被表示为(可以被视为)在层次结构中较高类的对象。
这方面最常见的例子是动物。许多来源用它来描述这个主题。
class Animal {};
class Dog : public Animal {};
int main() {
// 所有狗都是动物:OK
Animal* a = new Dog();
// 并非每个动物都是狗:错误
Dog* d = new Animal();
}
想象一下,你正在创建一个游戏,玩家有宠物。
class WrongPlayer {
Dog* pet;
}
按照这种方式,你只能拥有狗作为宠物。
class CorrectPlayer {
Animal* pet;
}
在这种情况下,你可以拥有任何从Animal继承的类作为宠物。这只是多态性用法的一个简单示例。
- 引用。
解释引用是什么的最佳方式是将它们视为别名。
创建引用与创建别名完全相同。
通过这种方式也很容易理解所有的限制。
示例:
int a = 5;
int& b = a; // b是a的别名
b = 3; // a = 3
- 解引用。
new
返回一个指针,所以要处理它所指向的对象,你必须首先对其进行解引用。
示例:
int* val = new int(1);
val = 5; // 错误,不能将整数分配给指针
*val = 5; // OK
delete val;
- 临时对象,它们被立即创建和删除。
示例:
class A {
public:
A() { std::cout << "Created" << std::endl; }
~A() { std::cout << "Destroyed" << std::endl; }
}
int main {
A();
std::cout << "应该在销毁之前打印吗?不应该!" << std::endl;
return 0;
}
在你的情况下,你执行以下操作:
在堆中分配一个对象并返回其指针。
new Deriv()
对该指针进行解引用。
*(new Deriv())
创建一个引用并将其绑定到新创建的对象上。
在这里,我们开始遇到一些问题。它不是临时对象!你在堆中的对象永远不会被销毁。
这是明显的内存泄漏。
我不知道为什么你要创建一个引用。
最佳方法是创建一个指针。
Base* ptr = new Deriv();
然后
delete ptr;
就这样。
但是,你也可以这样删除它
Base& ref = *(new Deriv());
delete &ref;
英文:
First, you need to be familiar with Polymorphism, references, dereferencing and temporary object behavior.
- Every object of some Class can be represented as (can be treated as) an object of a Class that is higher in the hierarchy.
The most popular examples of this are animals. Many sources describe this topic with it.
class Animal {};
class Dog : public Animal {};
int main() {
// All dogs are animals: OK
Animal* a = new Dog();
// Not every animal is a dog: Error
Dog* d = new Animal()
}
Imagine you are creating a game, where your player has a pet.
class WongPlayer {
Dog* pet;
}
If you put it this way, you will be able to have only Dog as pet.
class CorrectPlayer {
Animal* pet;
}
In this case, you can have as pet any class that inherits from Animal.
This was just one simple example of the usage of Polymorphism.
- References.
The best way of explaining what references are is to treat them as aliases.
Creating a reference is completely identical of creating an alias.
And all the restrictions are also well understood by this way.
Example:
int a = 5;
int& b = a; // b is alias of a
b = 3; // a = 3
- Dereferencing.
new returns a pointer, so to work with the object it points to, you have to first dereference it.
Example:
int* val = new int(1);
val = 5; // Error can't assign int to pointer
*val = 5; OK
delete val;
- Temporary objects, they are created and deleted immediately.
Example:
class A {
public:
A() { std::cout << "Created" << std::endl;}
~A() { std::cout << "Destroyed" << std::endl;}
}
int main {
A();
std::cout << "Should it be printed before destruction? No!" << std::endl;
return 0;
}
In your case, you do the following:
Allocate an object in heap and return its pointer.
new Deriv()
Dereference that pointer
*(new Deriv())
Create a reference and bind it with newly created object.
And here we start to have some problems. It is not a temporary object! Your object in heap never gets destroyed.
It is a clear memory leak
I don't know why are you creating a reference.
The best way is to create a pointer.
Base* ptr = new Deriv();
And then
delete ptr;
And that's it.
But yes, you can also delete it like this
Base& ref = *(new Deriv());
delete &ref;
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论