从虚拟方法返回派生对象作为基础
Returning derived object as base from virtual method
基 class 中有一些虚方法 return 相同的基对象(不是指针)。在一些虚拟覆盖中,我想 return 派生对象作为基础。但问题是该方法总是从 returning 派生创建基础对象。这是一个简单的例子:
#include <iostream>
#include <string>
class Base {
public:
Base() {}
virtual std::string myName() { return "Base"; }
virtual Base createAlike() { return Base(); }
};
class Derived : public Base {
public:
Derived() : Base() {}
std::string myName() override { return "Derived"; }
Base createAlike() override { return Derived(); }
};
int main() {
Derived d;
Base d1 = d.createAlike();
std::cout << d.myName() << std::endl;
std::cout << d1.myName();
return 0;
}
输出:
Derived
Base
如何更正?
由于您 return 按值,return 值是您 return 编辑的表达式的副本。由于 return 类型始终是 Base
,因此 Derived
对象被切片。要使多态性起作用,您通常需要一个指针或引用。
尝试使用 std::unique_ptr
:
#include <iostream>
#include <string>
#include <memory>
class Base {
public:
Base() {}
virtual std::string myName() { return "Base"; }
virtual std::unique_ptr<Base> createAlike()
{ return std::make_unique<Base>(); }
};
class Derived : public Base {
public:
Derived() : Base() {}
std::string myName() override { return "Derived"; }
std::unique_ptr<Base> createAlike() override
{ return std::make_unique<Derived>(); }
};
int main() {
Derived d;
auto d1 = d.createAlike();
std::cout << d.myName() << std::endl;
std::cout << d1->myName();
return 0;
}
基 class 中有一些虚方法 return 相同的基对象(不是指针)。在一些虚拟覆盖中,我想 return 派生对象作为基础。但问题是该方法总是从 returning 派生创建基础对象。这是一个简单的例子:
#include <iostream>
#include <string>
class Base {
public:
Base() {}
virtual std::string myName() { return "Base"; }
virtual Base createAlike() { return Base(); }
};
class Derived : public Base {
public:
Derived() : Base() {}
std::string myName() override { return "Derived"; }
Base createAlike() override { return Derived(); }
};
int main() {
Derived d;
Base d1 = d.createAlike();
std::cout << d.myName() << std::endl;
std::cout << d1.myName();
return 0;
}
输出:
Derived
Base
如何更正?
由于您 return 按值,return 值是您 return 编辑的表达式的副本。由于 return 类型始终是 Base
,因此 Derived
对象被切片。要使多态性起作用,您通常需要一个指针或引用。
尝试使用 std::unique_ptr
:
#include <iostream>
#include <string>
#include <memory>
class Base {
public:
Base() {}
virtual std::string myName() { return "Base"; }
virtual std::unique_ptr<Base> createAlike()
{ return std::make_unique<Base>(); }
};
class Derived : public Base {
public:
Derived() : Base() {}
std::string myName() override { return "Derived"; }
std::unique_ptr<Base> createAlike() override
{ return std::make_unique<Derived>(); }
};
int main() {
Derived d;
auto d1 = d.createAlike();
std::cout << d.myName() << std::endl;
std::cout << d1->myName();
return 0;
}