首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >调用常量函数而不是其非常量版本

调用常量函数而不是其非常量版本
EN

Stack Overflow用户
提问于 2011-09-03 01:22:09
回答 4查看 22.9K关注 0票数 31

我尝试包装一些类似于Qt的共享数据指针的东西来实现我的目的,经过测试,我发现当应该调用const函数时,却选择了它的非常量版本。

我正在使用C++0x选项进行编译,下面是一个最小的代码:

代码语言:javascript
复制
struct Data {
    int x() const {
        return 1;
    }
};

template <class T>
struct container
{
    container() {
        ptr = new T();
    }


    T & operator*() {
        puts("non const data ptr");
        return *ptr;
    }

    T * operator->() {
        puts("non const data ptr");
        return ptr;
    }

    const T & operator*() const {
        puts("const data ptr");
        return *ptr;
    }

    const T * operator->() const {
        puts("const data ptr");
        return ptr;
    }

    T* ptr;
};

typedef container<Data> testType;

void testing() {
    testType test;
    test->x();
}

如您所见,Data.x是一个常量函数,因此调用的运算符->应该是常量函数。当我注释掉非常数时,它编译时没有错误,所以这是可能的。但是我的终端打印出来了:

“非常数数据收件人”

是不是一个GCC的bug (我的版本是4.5.2),或者是我遗漏了什么?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-09-03 01:26:00

如果您有两个仅在const-ness方面不同的重载,那么编译器将根据*this是否为const来解析调用。在示例代码中,test不是const,因此调用非const重载。

如果你这样做了:

代码语言:javascript
复制
testType test;
const testType &test2 = test;
test2->x();

您应该会看到调用了另一个重载,因为test2const

票数 34
EN

Stack Overflow用户

发布于 2011-09-03 01:28:52

test是一个非常数对象,因此编译器会找到最佳匹配:非常数版本。不过,您可以使用static_cast应用常量:static_cast<const testType&>(test)->x();

编辑:顺便说一句,因为你怀疑99.9%的时间你认为你发现了一个编译器错误,你应该重新检查你的代码,因为可能有一些奇怪的怪癖,而编译器实际上是遵循标准的。

票数 12
EN

Stack Overflow用户

发布于 2011-09-03 01:28:06

Data::x是不是一个常量函数并不重要。被调用的运算符属于container<Data>类而不是Data类,并且它的实例不是常量,所以调用非常量运算符。如果只有常量运算符可用,或者类的实例本身是常量,那么就会调用常量运算符。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/7287065

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档