将派生指针隐式强制转换为其相应基类的引用
Implicit casting of a derived pointer to a reference of its corresponding base
我有一个函数,看起来像:
// this function might modify base_ptr
void SomeFunction(shared_ptr<Base> &base_ptr)
{ if(some_condition) { base_ptr = some_other_ptr; } }
我想用shared_ptr来调用函数:
shared_ptr<Derived> d = ...;
SomeFunction(d);
这不起作用。它不工作,如果我使用普通指针(即。对Base* &从派生的*。一种解决方法是从派生指针创建一个基指针,然后将其传递给函数。
shared_ptr<Base> base = d;
SomeFunction(b);
但是从编码的角度来看,这不是很漂亮。它还增加了混淆和潜在的细微错误:
shared_ptr<Derived> d = derived;
shared_ptr<Base> b = derived;
SomeFunction(b);
// b and d might now be pointing to different things -- not good!
有更好的方法吗?
你试图做的事情本质上是危险的,c++故意让它变得困难。考虑一下c++是否允许您以想要的方式调用SomeFunction
。然后你可以这样做:
struct Base {
};
struct Derived1 : Base {
void f1();
};
struct Derived2 : Base {
void f2();
};
void SomeFunction(shared_ptr<Base> &p)
{
p = make_shared<Derived2>(); // nothing wrong with converting
// a Derived2 pointer to a Base pointer.
}
int main()
{
shared_ptr<Derived1> d = make_shared<Derived1>();
SomeFunction(d); // An error, but what if it wasn't?
d->f1(); // Trying to call method f1 of a Derived2!
}
编译器将无法知道d
从Derived1
指针变为Derived2
指针,因此当您试图调用Derived2
的f1
方法时,它将无法给您编译错误。
你可以为智能指针的类型模板化函数
#include <iostream>
#include <memory>
#include <type_traits>
using namespace std;
class Base {
public:
virtual void hello() {
cout << "hello base" << endl;
}
};
class Derived : public Base {
public:
void hello() {
cout << "hello derived" << endl;
}
};
class otherClass {
public:
};
template<typename T>
void SomeFunction(shared_ptr<T> &base_ptr)
{
static_assert(is_base_of<Base, T>::value == true, "Wrong non-derived type");
base_ptr->hello();
// Rebase it
base_ptr.reset(new Derived);
base_ptr->hello();
}
int main() {
shared_ptr<Base> obj(new Base());
SomeFunction(obj);
// hello base
// hello derived
shared_ptr<Derived> obj2(new Derived());
// hello derived
// hello derived
SomeFunction(obj2);
shared_ptr<otherClass> obj3(new otherClass());
SomeFunction(obj3); // ASSERT
return 0;
}
http://ideone.com/ATqhEZ 如果你打算在重置一个智能指针时更新所有的智能指针,你必须自己做一些簿记工作,因为它们没有被设计成具有"类似信号"的机制来通知指向同一对象的其他智能指针。
编辑了我的答案,如果你打算将它与基类和相对子类一起使用,则提供编译时安全性。
警告:上述解决方案使用c++ 11,同样可以在c++ 11之前的代码中以类似的方式完成
相关文章:
- 如何使用基类指针引用派生类成员
- 如何引用基类的派生类?
- 我可以引用模板的基类吗?
- 通过基类接受方法转发派生 UniquePtr 的右值会移动引用而不是复制
- 如何复制只引用基类的派生类
- 引用基类模板的成员变量的简单方法
- C++ 构造函数传递对基类对象的引用
- 从引用创建指向基类的智能指针
- C++ 为什么要将对基类的引用传递给派生类的构造函数
- 通过基类引用派生类后打印的错误值
- 如何在 c++ 中通过基类引用访问派生类的对象?
- 将对成员的引用传递给基类的构造函数
- 从基类的共享指针向下转换到派生类的引用
- 有条件地将基类引用参数视为派生类并将其返回
- 将派生类指针强制转换为基类引用
- 派生类函数参数作为基类引用导致C2678
- 是否可以使用对派生类实例的基类引用初始化派生类引用
- 从c++中另一个(不相关的!)类的基类引用派生类的对象
- 从基类引用派生类参数
- 在这种情况下,将派生类传递到具有基类引用arg的函数中,我会得到切片吗?