2009-07-13 47 views
2

我有一个转换运算符返回一个const指针,我需要const_cast它。但是,这至少在MSVC8下不起作用。以下代码重现了我的问题:为什么我不能const_cast转换运算符的返回?

class MyClass { 
public: 
    operator const int*() { 
     return 0; 
    } 
}; 

int main() { 
    MyClass obj; 
    int* myPtr; 
    // compiles 
    const int* myConstPtr = obj; 
    // compiles 
    myPtr = const_cast<int*>(myConstPtr); 
    // doesn't compile (C2440: 'const_cast' : cannot convert from 'MyClass' to 'int *') 
    myPtr = const_cast<int*>(obj); 
} 

这是为什么?这似乎违反直觉。谢谢!

+1

你真的想试着用`const int *`返回一个空指针吗?能够默默地将类转换为指向原语的指针通常也是不好的做法。 (例如,`std :: string`不能转换成`const char *`,而是提供一个`.c_str()`方法来返回一个指向它的数据的指针,这样更安全,因为程序员必须非常意识到他在做什么。) – 2009-07-13 13:20:03

+0

@Seth:谢谢。这不是我真正的代码;这只是我写的重现我得到的错误!请放心,我没有特意返回空指针:-)就我而言,这个类是一个围绕字节数组的薄包装,我希望它的客户端使用它,就好像它是一个一样。 – 2009-07-13 13:23:21

+0

如果你打算让用户能够直接操作字节数组,那么你应该给它们一个非const的操作符int *()`。一般只给出const版本意味着你允许读取但不能修改。强迫用户执行`const_cast`是我的书中的一个错误。 – 2009-07-13 13:39:56

回答

4

为了使它工作,你需要做的:

myPtr = const_cast<int*>(static_cast<const int*>(obj)); 

当你的const_cast直接,编译器看的类型转换操作符为int *。

1

您只能使用const_cast转换为相同类型的非常量指针(以抛弃常量)。要在不相关的类型之间进行投射,您需要reinterpret_cast。

myPtr = const_cast<int*>(obj()); 

我还没有尝试过呢,心想:

-1

也许如果你做类似的东西会更清楚你的编译器。

编辑: 不应该符声明是这样的:

const int* operator() { 
1

思考的const_cast<>作为一个函数模板

template <typename Target, typename Source> 
Target const_cast(Source src); 

(这不是它是如何实现的,但它可以帮助这里想象它是)。然后Source推导为MyClass,并没有什么const_cast可以做从一个MyClass获取int *。

你想要的是以下任一:

const_cast<int*>(static_cast<const int*>(obj) /* invokes operator const int* */); 
// or 
const_cast<int*>(obj.operator const int*()); 
1

const_cast只能改变一个类型的常量。如果你想打电话给隐式算子,你需要一个static_cast然后一个const_cast。虽然它很烦人,但它确保你清楚你在做什么。

myPtr = const_cast<int*>(static_cast<const int*>(obj)); 

您也可以使用旧学校C风格的类型转换操作符

myPtr = (int*)(const int*)obj; 

但这种强烈鼓励有以下几个原因:

  • 它不是的grepable
  • 你可以非常轻松地做到超出您的预期。大多数情况下,您不想与const_cast类型操作混淆,并使用static_cast来强制执行此操作。实际上你很少想要一个const_cast。如果你发现自己经常做这件事,你会有一些设计错误。

编辑:我稍微关了一下,我现在就修好了。这使得C风格演员有点丑陋

相关问题