我有以下代码:
main.hxx:
#include <iostream>
class Base{
public:
Base() {}
~Base() {}
virtual void whoAreYou() { std::cout << "I am base!" << std::endl;}
};
class Sub : public Base{
public:
Sub() {}
~Sub() {}
virtual void whoAreYou() { std::cout << "I am Sub!" << std::endl;}
};
class Factory {
public:
static Base getBase() { return Base(); }
static Base* getBasePtr() { return new Base(); }
static Base getSub() { return Sub(); }
static Base* getSubPtr() { return new Sub(); }
};
main.cxx
#include "main.hxx"
int main (int argc, char **argv) {
// Non pointers
Factory::getBase().whoAreYou();
Factory::getSub().whoAreYou();
// Pointers
Base* basePtr = Factory::getBasePtr();
Base* subPtr = Factory::getSubPtr();
basePtr->whoAreYou();
subPtr->whoAreYou();
delete basePtr, subPtr;
return 0;
}
运行时,会打印以下内容:
I am base!
I am base!
I am base!
I am Sub!
我期待“Factory :: getSub()。whoAreYou();”打印“我是Sub!”。是不是因为当不使用指针时它会被转换为Base?
答案 0 :(得分:2)
此行创建Sub
,然后调用Base
默认复制构造函数,以从实例Base
创建Sub
的实例:
static Base getSub() { return Sub(); }
因此你的日志。
更多通常Base
是Base
实例,而Base*
是Base
实例上的指针或继承Base
的对象。
答案 1 :(得分:2)
我期待
Factory::getSub().whoAreYou();
打印“我是Sub!”。
不,该函数返回Base
,因此你得到Base
。
是不是因为当没有使用指针时它会被转换为Base?
是(尽管单词“已转换”而非“已转换” - 演员表是一种显式转换,此转换是隐式的)。这有时被称为“切片”,因为对象的派生类部分在复制时会被“切掉”。
另外,请注意以下事项:
delete basePtr, subPtr;
仅删除subPtr
。每个都需要一个单独的删除表达式。您还需要Base
中的虚拟析构函数来安全删除subPtr
。