将指针对齐以具有功能性 - >操作? C ++

时间:2014-10-20 17:43:03

标签: c++ pointers c++11 dependency-injection

这个问题由几个部分组成,第一部分与一个类中的->运算符有关。是否需要某种输入(根据C ++标准)?例如

some_return_type? operator->( long address ) {
    cast the address to some sort of pointer and do something with it...
    return something?...possibly... maybe not?;
}

所以实际上A::SomeMethod()会引用传递给->的内存函数的地址。要么 A::someStaticOrNonStaticDataMember会引用字段的地址吗?

如果是这样(假设我们可以访问类的实际类型),或者存在类似的东西,它是什么,我们可以重建指针的一部分,或者对齐一个指针,(或写一个算法来做这个),对于一个基于该类的一些信息的类,以便它有一个可操作的->运算符,所以可以写:

somePointer->A::SomeMethod();

让它调用A :: SomeMethod()?并且可能为类中使用的内存创建上下文?

3 个答案:

答案 0 :(得分:2)

从评论中,您似乎想要控制编译器处理和生成->令牌的方式。这是因为你的运气不可能,因为编译器没有公开这些信息,标准也不需要这样做

答案 1 :(得分:1)

箭头运算符( - >)是一个解引用运算符,专门用于指向具有成员的对象的指针。
foo->bar()(*foo).bar()

相同

如果你想超载 - >你也应该超载*

答案 2 :(得分:1)

就像你试图拥有“动态”(C#类型),但在C ++中,不幸的是这是不可能的。可能类似的是包装某种由字符串(一种脚本语言)处理的“Closure集合”,但这会非常沉重而且不是很好。

实际上无法使用您显示的语法执行您想要的操作。

如果对象的类型未知,那么您将该对象隐藏在“void *”后面。这基本上意味着您可以使用该对象的唯一方法是将其转换回原始类型。

假设您有一个暴露2个函数的DLL(带有头文件)

// creates an object of given type or null_ptr if no object match
void* getObject(std::string obj_type);

// call a method on that object
void callMethod(void* obj, std::string method_name, void* args, void* returnval);

实际上,该解决方案(即使丑陋)允许在您不知道的对象上调用方法(它可能比这更好。) 但这迫使你使用void *和字符串。那是因为C ++如何解析方法名称(实际上也是在C#中,“动态”类型在幕后生成反射代码,使用带有方法名称的字符串并且特别慢)

使用

可以实现类似的功能
float fuelLiters = 3.0f;
void * myObj = createObject("SomeCar");
callMethod(myObj,"loadFuel", &fuelLiters, null_ptr);

你可能会使用模板或某些宏来改善语法,但你永远无法做到像

这样的事情。
myObj->A::loadFuel(fuelLiters);

你可以做的是拥有外部加载的类,使用你的应用程序的相同接口,说:

class ICar{
    public:

    void loadFuel(float liters)=0;
};

在这种情况下,您可以使用将不透明对象句柄强制转换为ICar的函数。这就是我在2年前写的一个库中已经做过的事情:

所以你只需要DLL公开一个用于转换类的方法(向下转换)

//if given object is implementing a ICar, the correct pointer is returned, else
// this function will return nullptr (or throw exception if you like more)
void * downcast( typeof(ICar), myObj);

你需要简单地

ICar *myCar = static_cast<ICar>(downcast( typeof(ICar), myObj));
myCar->loadFuel(3.0f);

但请注意,DLL和您的应用程序都应该“知道”“ICar”是什么,因此它们必须包含“ICar”标题。

这样做肯定是可能的,我已经用两种不同的方式做到了,所以如果你需要更多关于实现的细节,我会很乐意展示一种可能的方式(鉴于我理解你的问题)。