[英]How to overload the arrow dereference operator->() not for solid objects but for pointers
我知道如何为实体(堆栈)对象(如智能指针)重载operator->
#include <iostream>
struct A { void foo() {} };
struct B {
A* pa;
A* operator->() {
return pa;
}
};
int main() {
B b;
b->foo(); // b is SOLID object on stack: b.pa = ...
}
但是我想要这个:
B * pb = new B();
pb->foo(); // to call my overload
对于数据库管理器Singleton设计,我需要此功能:
class DatabaseManager
{
private:
static DatabaseManager * sharedInstance_;
sqdb::Db *db = nullptr;
public:
static DatabaseManager * instance();
sqdb::Db * operator->() {
return db;
}
}
我基本上想要这种行为
auto m = DatabaseManager::instance();
m->Query(...); // db->Query
您不能在指针上替换->
。
您可以创建一个重载->
的智能指针1 ,但是内置操作符可能不会重载。
auto m = DatabaseManager::instance();
m->Query(...); // db->Query
没问题,但是m
类型不是指针。 它是某些带有重载operator->
struct
或class
。
这样的类可以只是unique_ptr
或shared_ptr
的薄包装,例如->
可以返回&(ptr.get()->db)
。
最愚蠢的方法是
class DatabaseManager {
struct DatabaseManagerPtr {
DatabaseManager* ptr;
sqdb::Db * operator->() {
return ptr?ptr->db:nullptr;
}
};
friend struct DatabaseManagerPtr;
private:
static DatabaseManager * sharedInstance_;
sqdb::Db *db = nullptr;
public:
static DatabaseManagerPtr instance() {
return {sharedInstance_};
}
};
这会使您的“我希望它能正常工作”代码完全按原样工作,但是还有许多更聪明的方法可以做到这一点(这可能会对您的“我想让它正常工作”代码进行些微调整)
1在C ++中,智能指针是行为类似于指针的任何类型,但以合理合理的方式比原始指针“更聪明”。 也许它只是穿着一套高级西装。 C ++在称事物为“智能”指针方面不是很精英。
规则是:
如果
T::operator->()
存在并且如果选择运算符作为最佳匹配函数,则表达式T
的类对象x
的表达式x->m
解释为(x.operator->())->m
。通过过载解析机制
和
当operator->返回时,将运算符->应用于具有原始第二个操作数的返回值。
太容易理解了:只能将.operator->()
链式调用简化为单个->
,然后也将减少“以下”对指针的取消引用。
因此,在这种情况下,只需更改instance
函数以返回DatabaseManager&
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.