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++_Constants_Overload Resolution_Const Reference_Const Method - Fatal编程技术网

C++ 在c++;,为什么编译器选择非常量函数,而常量也可以工作?

C++ 在c++;,为什么编译器选择非常量函数,而常量也可以工作?,c++,constants,overload-resolution,const-reference,const-method,C++,Constants,Overload Resolution,Const Reference,Const Method,例如,假设我有一个类: class Foo { public: std::string& Name() { m_maybe_modified = true; return m_name; } const std::string& Name() const { return m_name; } protected: std::string m_name; bool m_

例如,假设我有一个类:

class Foo
{
public:
    std::string& Name()
    {
        m_maybe_modified = true;
        return m_name;
    }

    const std::string& Name() const
    {
        return m_name;
    }
protected:
    std::string m_name;
    bool m_maybe_modified;
};
在代码的其他地方,我有这样的东西:

Foo *a;
// Do stuff...
std::string name = a->Name(); // <-- chooses the non-const version
Foo*a;
//做些事情。。。

std::string name=a->name();// 我想到两个答案:

  • 非常量版本更接近

  • 如果它为非常量情况调用常量重载,那么在什么情况下它会调用非常量重载

  • 通过将
    a
    强制转换为
    const Foo*
    ,可以让它使用另一个重载

    编辑:来自

    前面,在第2.5.11节中 函数重载的定义是 介绍。在那里,它注意到该成员 函数可能仅通过 它们的常量属性。在这些情况下, 编译器将使用该成员 函数与 对象的常量限定:


    因为a不是常量指针。因此,非常量函数更接近匹配。以下是如何调用const函数:

    const Foo* b = a;
    std::string name = b->Name();
    

    如果您同时具有常量和非常量重载,并且希望在非常量对象上调用常量重载,这可能表明设计不好。

    编译器在确定时没有考虑您如何使用返回值;这不是规则的一部分。它不知道你在做什么

    std::string name = b->Name();
    

    它必须选择在这两种情况下都适用的版本。

    您可以添加一个与“Name()const”等效的“cName”函数。通过这种方式,您可以调用函数的const版本,而无需首先强制转换到const对象

    这对于C++0x中的新关键字auto非常有用,这就是为什么他们要更新库以包括cbegin()、cend()、crbegin()、crend()以返回常量迭代器,即使对象是非常量


    最好使用setName()函数来更改名称,而不是返回对底层容器的引用,然后“可能”对其进行修改。

    问题不在于返回值的常量与否,而在于对象的常量。虽然-1不是我。我理解编译器可能存在的问题,但我认为它能够进行一些简单的检查,例如在示例中,它将立即使用返回值来获取副本,然后丢弃它。这将非常危险,因为对其他代码行的更改也会导致该特定调用的行为发生更改。确定过载分辨率的规则已经够复杂了。完整的设计很难用一个例子来表达,但我相信有几点可以改进。。。我们目前使用的是const指针方法,但它很难看,更重要的是依赖于程序员记住这样做。给const重载一个不同的名称如何?或者同时有一个常量重载和一个不同名称的函数,一个调用另一个,这是一个错误。。。指针不是常量。。。在您的示例中,它是一个“指向常量的指针”。我知道使用setName()函数可能会更好,但同样,这个示例有些做作。实际上,我们有包含其他对象的指针对象,并且希望在可能的情况下返回常量指针,将它们串成“int c=a->B()->GetC();”等。如果您想更改常量函数中的一些变量,我想可以使用mutual属性…和“member variables”。
    b->Name() = "me";