Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 从常量成员函数调用非常量成员函数指针_C++_C++11 - Fatal编程技术网

C++ 从常量成员函数调用非常量成员函数指针

C++ 从常量成员函数调用非常量成员函数指针,c++,c++11,C++,C++11,我有以下代码: class MyClass; typedef void(MyClass::*func_ptr)(); class MyClass { public: MyClass() { f = &MyFunc1; } void MyFunc1() { // ... } void MyFunc2() const { (this->*f)(); } func_ptr f; }; 如果我尝试编译,它会失败,因为MyFunc2()是一个常量方法,它试

我有以下代码:

class MyClass;
typedef void(MyClass::*func_ptr)();
class MyClass
{
public:

MyClass()
{
    f = &MyFunc1;
}

void MyFunc1()
{
    // ...
}

void MyFunc2() const
{
    (this->*f)();
}

func_ptr f;

};
如果我尝试编译,它会失败,因为MyFunc2()是一个常量方法,它试图调用类型为func_ptr的非常量函数指针

我想找出最好的方法来演这个。我可以使用标准的C样式转换:

    typedef void(MyClass::*func_ptr2)() const;
    func_ptr2 f2 = (func_ptr2)f;
    (this->*f2)();

<>但是我更喜欢使用C++的CAST(即STATICE-CAST,RealType CAST或COSTRYCAST)。我用reinterpret_cast编译了这个,但是我不能用const_cast编译它。我以为const_cast不适合这个案子?另外,是否有一种更干净的方法可以做到这一点,而不必创建另一个typedef?

此代码中有几个问题

 f = &MyFunc1;

不是很好的C++,因为使用非静态成员函数的地址需要完全限定名:

 f = &MyClass::MyFunc1;

是常量成员函数中的
MyClass const*
。您可能需要扔掉
常量

(const_cast<MyClass*>(this)->*f)();
(const_cast(this)->*f)();

一个更好的解决方案可能是重新考虑设计,以避免与类型系统发生冲突

 f = &MyFunc1;

不是很好的C++,因为使用非静态成员函数的地址需要完全限定名:

 f = &MyClass::MyFunc1;

是常量成员函数中的
MyClass const*
。您可能需要扔掉
常量

(const_cast<MyClass*>(this)->*f)();
(const_cast(this)->*f)();

一个更好的解决方案可能是重新考虑设计,以避免使用
const_cast

来对抗类型系统。典型的解决方案是
(const_cast(this)->*f)()

只要创建了非常量的
MyClass
实例,这是合法的。
否则,这将调用未定义的行为。

典型的解决方案是
(const_cast(this)->*f)()

只要创建了非常量的
MyClass
实例,这是合法的。
否则,这将调用未定义的行为。

以下内容似乎已编译:

MyClass()
{
    f = &MyClass::MyFunc1;
}

void MyFunc1()
{
    // ...
}

void MyFunc2() const
{
    MyClass* mc = const_cast<MyClass*>(this);
    (mc->*f)();
}
MyClass()
{
f=&MyClass::MyFunc1;
}
void MyFunc1()
{
// ...
}
void MyFunc2()常量
{
MyClass*mc=常量(此);
(mc->*f)();
}

以下内容似乎已编译完成:

MyClass()
{
    f = &MyClass::MyFunc1;
}

void MyFunc1()
{
    // ...
}

void MyFunc2() const
{
    MyClass* mc = const_cast<MyClass*>(this);
    (mc->*f)();
}
MyClass()
{
f=&MyClass::MyFunc1;
}
void MyFunc1()
{
// ...
}
void MyFunc2()常量
{
MyClass*mc=常量(此);
(mc->*f)();
}

如何有一种干净的方法从
const
函数调用非
const
函数。其中一个函数是
const
,而另一个不是,这可能是有原因的。如果不是这样,只需修改
const
限定符。在我看来,上面的注释(由@FrankPuffer)应该被认为是这个问题的正确答案。如果这些函数的“const ness”确实不同,那么不要从const函数中调用非const函数。如果它们没有区别,那么只需更改(不正确的)声明。如何有一种干净的方法从
const
函数调用非
const
函数呢。其中一个函数是
const
,而另一个不是,这可能是有原因的。如果不是这样,只需修改
const
限定符。在我看来,上面的注释(由@FrankPuffer)应该被认为是这个问题的正确答案。如果这些函数的“const ness”确实不同,那么不要从const函数中调用非const函数。如果它们没有区别,那么只需更改(不正确的)声明。仅仅因为程序编译并不意味着它是有效的,或者是一个好主意。这是一个公平的观点。我不是故意这么说的,因为它把它编译得很好。我在写这篇文章的同时,还有另外两个人在提供答案。阅读他们的文章,代码部分似乎有些相似。仅仅因为程序编译并不意味着它是有效的,或者是一个好主意。这是一个公平的观点。我不是故意这么说的,因为它把它编译得很好。我在写这篇文章的同时,还有另外两个人在提供答案。阅读他们的文章,代码部分似乎有些相似。