调用子类方法。指针与非指针

时间:2013-11-22 15:47:08

标签: c++ pointers inheritance

我有以下代码:

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?

2 个答案:

答案 0 :(得分:2)

此行创建Sub,然后调用Base默认复制构造函数,以从实例Base创建Sub的实例:

static Base getSub() { return Sub(); }

因此你的日志。

更多通常BaseBase实例,而Base*Base实例上的指针或继承Base的对象。

答案 1 :(得分:2)

  

我期待Factory::getSub().whoAreYou();打印“我是Sub!”。

不,该函数返回Base,因此你得到Base

  

是不是因为当没有使用指针时它会被转换为Base?

是(尽管单词“已转换”而非“已转换” - 演员表是一种显式转换,此转换是隐式的)。这有时被称为“切片”,因为对象的派生类部分在复制时会被“切掉”。

另外,请注意以下事项:

delete basePtr, subPtr;

仅删除subPtr。每个都需要一个单独的删除表达式。您还需要Base中的虚拟析构函数来安全删除subPtr