重载,const参数,const_cast,const_cast <string&=“”>

时间:2018-04-12 10:08:44

标签: c++ reference

我正在阅读 C ++ Primer ,我发现了一些非常奇怪且难以理解的东西:

Record lookup(Account&);  //Record and Account are two unrelated class
Record lookup(const Account&);

所以这两个函数都接受非const对象(首先匹配非const参数函数),但只有第二个函数可以接受const对象。

从下一节( const_cast和overloading )我有这些代码:

const string &shorterString(const string &s1, const string &s2){
   return s1.size() < s2.size() ? s1 : s2;
}   

string &shorterString(string &s1, string &s2){
   auto &r = shorterString(const_cast<const string&>(s1),
                           const_cast<const string&>(s2));
   return const_cast<string &>)(r);
}

const_cast<const string&>(s1)究竟是什么意思?

据我所知:

  

引用是对象,只是另一个名称。它既不是指向对象的指针,也不是对象的副本。这是对象。

所以我传递一个字符串对象来初始化引用s1,所以s1本身就是一个字符串对象,那么它如何将string转换为const string&然后呢匹配其他功能?

应该如何理解函数调用?

shorterString(const_cast<const string&>(s1),const_cast<const string&>(s2));

是否使用引用来初始化引用?但是因为引用本身就是一个对象,所以我使用的是s1引用初始化的对象及其字符串。再次,const_cast<const string&)(s1)stringconst string&

从我的角度来看,如果你有一个字符串对象,那么你只能匹配非const引用参数函数,并且没有类似的东西:

string s1 = "abc";
string s2 = "efg";
shorterString(const(s1), const(s2));   //no such top-level const cast

PS:当谈到非const和const指针参数时,这是可以理解的。

如果是单调乏味的问题,我上传了相关段落的截图:

  1. https://imgur.com/tnqrxVY
  2. https://imgur.com/hF1MjUH
  3. https://imgur.com/Fg2zeEw

2 个答案:

答案 0 :(得分:0)

有两个重载函数。一个用于与常量对象一起使用,另一个用于与非常量对象一起使用。

非常量对象的函数实现是在对常量对象的函数调用的基础上构建的。

如果删除参数的转换,那么非常量对象的函数将尝试递归调用自身。

要允许编译器为非常量对象选择函数内的常量对象,必须使用const__cast显式地转换参数。

同样,当常量对象的函数返回常量引用,而非常量对象的函数返回非常量引用时,必须将常量对象的函数的返回引用强制转换为非常量引用。

所以首先你必须抛出参数ro常量引用来调用常量对象的函数,然后你必须再次将常量对象的函数的返回引用强制转换为非const引用。

这是一个示范程序。

#include <iostream>
#include <string>

const std::string & shorterString( const std::string &s1, const std::string &s2 )
{
    std::cout << 
        "const std::string & shorterString( const std::string &, const std::string )"
        " called\n";
    return s2.size() < s1.size() ? s2 : s1;
}   

std::string & shorterString( std::string &s1, std::string &s2 )
{
    std::cout << 
        "std::string & shorterString( std::string &, std::string )"
        " called\n";
   return const_cast<std::string &>( shorterString( const_cast<const std::string&>( s1 ),
                                                    const_cast<const std::string&>( s2 ) ) ); 
}

int main() 
{
    std::string s1 = "abc";
    std::string s2 = "efg";

    shorterString( s1, s2 );

    std::cout << std::endl;

    shorterString( const_cast<const std::string &>( s1 ), 
                   const_cast<const std::string &>( s2 ) );

    return 0;
}

它的输出是

std::string & shorterString( std::string &, std::string ) called
const std::string & shorterString( const std::string &, const std::string ) called

const std::string & shorterString( const std::string &, const std::string ) called

答案 1 :(得分:0)

为什么删除我以前的答案?我重申了我是如何得到混乱的

  

就像我说的那样,我曾经认为引用及其引用在某种程度上是相同的。所以我对使非const对象与const引用参数匹配感到非常困惑。

并给出答案:

  

将参考作为一种特殊的指针。从这个角度看,一切似乎都有意义。

这是我对这两个相关问题的结论和答案。这可能对像我这样的新手有所帮助。

如果你真的觉得那没用,那么随意删除整个问题。