如何在C ++中将Foo **指针转换为const Foo **

时间:2009-08-20 21:20:47

标签: c++ pointers casting

我有

class Fred 
{
public:
  void inspect() const {}; 
  void modify(){};
};

int main()
{
 const Fred x = Fred();
 Fred* p1;
 const Fred** q1 = reinterpret_cast<const Fred**>(&p1);
 *q1 = &x; 
 p1->inspect();
 p1->modify();
}

怎么可能这样做 const Fred ** q1 =&amp; p1 通过指针铸造?

(我刚刚读到这可能是可能的)

感谢您的回答。 const_cast确实适用于对象

#include <iostream>
#include <stdio.h>
using namespace std;

class Fred 
{
 int a;

public:
Fred(){};
Fred(int a_input)
{
 a = a_input;
};

void inspect() const 
{
 cout << "Inspect called"<< endl;
 cout << "Value is ";
 cout << a << endl;
}; 

void modify()
{
 cout << "Modify called" << endl;
 a++;
};

};

int main()
{
 const Fred x = Fred(7);
 const Fred* q1 = &x;
 Fred* p1 = const_cast<Fred*>(q1); 
 p1->inspect();
 p1->modify();
 p1->inspect();
 x.inspect();
 *p1 = Fred(10);
 p1->inspect();
}

给出

Inspect called
Value is 7
Modify called
Inspect called
Value is 8
Inspect called
Value is 8
Inspect called
Value is 10
Inspect called
Value is 10

但是,对于预定义类型,它不起作用:

int main()
{
 const double a1 = 1.2;
 const double* b1 = &a1;
 cout << "a1 is " << (*b1) << endl;
 cout << "b1 is " << b1 << endl;
 double* c1 = const_cast<double*>(&a1);
 cout << "b1 is " << b1 << endl;
 cout << "c1 is " << c1 << endl;

 double* d1 = static_cast<double*>(static_cast<void*>(c1));
 cout << "d1 is " << d1 << endl;
 cout<< "*d1 is " << *d1 << endl;

 *d1=7.3;

 cout<< "*d1 is " << *d1 << endl;
 cout<< "*d1 address is "<< d1 << endl;
 cout << "a1 is " << a1 << endl;
 cout << "a1 address is" << &a1 << endl;
 cout<< "*d1 is " << *d1 << endl;
 cout<< "*d1 address is "<< d1 << endl;

 double f1=a1;
 printf("f1 is %f \n", f1);
}

导致:

a1 is 1.2
b1 is 0xffbff208
b1 is 0xffbff208
c1 is 0xffbff208
d1 is 0xffbff208
*d1 is 1.2
*d1 is 7.3
*d1 address is 0xffbff208
a1 is 1.2
a1 address is0xffbff208
*d1 is 7.3
*d1 address is 0xffbff208
f1 is 1.200000 

显然g ++编译器会优化它,只要它找到它就会将a1替换为1.2,因此,即使它在堆栈上的值发生了变化,它也无关紧要。

(在我的情况下,我遇到了直接读取* b1,* c1的问题,所以我不得不进行双重静态演员 - 重新解释演员不起作用)。

有没有办法真正改变a1,编译“正常”,因此没有优化就不编译(所以我超越了优化效果)?

6 个答案:

答案 0 :(得分:17)

这应该这样做:

Foo** f;
const Foo** cf = const_cast<const Foo**>(f);

答案 1 :(得分:10)

这不是一个好主意,因为它违反了类型安全。让我解释一下原因:

Fred* pFred;
const Fred** ppFred = const_cast<const Fred**>(&p);

*ppFred = new const Fred;  // Now pFred points to a const Fred

pFred->some_evil_mutating_method(); // can do, since type of *pFred is non-const!

答案 2 :(得分:3)

你想要const_cast

答案 3 :(得分:1)

你为什么不这样做:?

const Fred** q1;
*q1 = p1;

或者你想在没有const_cast的情况下忽视constness违规? - 不,先生,你不能。

答案 4 :(得分:0)

你不应该这样做。您无法轻松进行转换的事实是因为它打破了常量的正确性(并且您的代码会对其进行操作)。使用上面的建议,您的代码将编译并将在常量对象(最后一行代码)上调用变异方法。

不建议这样做,在某些极少数情况下甚至可以杀死你的应用程序(一个常量的全局对象可以存储在一个只读的内存页面中),或者让它处于不稳定的状态(通过以下方式改变对象的内部状态)通过常量引用更改为内部成员元素,打破对象不变量。)

关于您的问题:C++ FAQ Lite [18.17]

答案 5 :(得分:-1)

您不需要为const Fred** q1 = &p1进行任何投射,因为非const Fred**可以在其声明中直接分配给const Fred** q1