c++ - 重载、const 参数、const_cast、const_cast<string &>

标签 c++ reference

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

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

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

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

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)意思是?

我被告知:

A reference is the object, just with another name. It is neither a pointer to the object, nor a copy of the object. It is the object.

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

函数调用应该怎么理解?

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

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

在我看来,如果你有一个字符串对象,那么你只能匹配非常量引用参数函数,而没有像:

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

最佳答案

有两个重载函数。一种设计用于常量对象,另一种设计用于非常量对象。

非常量对象函数的实现建立在常量对象函数的调用之上。

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

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

此外,由于常量对象的函数返回常量引用,而非常量对象的函数返回非常量引用,因此您必须将常量对象函数的返回引用转换为非常量引用。

所以首先你必须将参数转换为常量引用以调用常量对象的函数,然后你必须再次将常量对象的函数的返回引用转换为非常量引用..

这是一个演示程序。

#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

关于c++ - 重载、const 参数、const_cast、const_cast<string &>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49793818/

相关文章:

Java:更改堆上的对象引用?

c++ - 从 QtreeView 列表中获取字符串

c++ - 使用 typedef 摆脱 GCC 中的 `deprecated conversion from string constant to ‘char*’ ` 警告?

C# 自动引用分配 - 使引用为空

c# - Visual Studio - 为具有相同名称的程序集构建不同版本

c++ - 如何将 boost::shared_ptr<> 变成引用 (&)?

c++ - 如何为 QML 创建通用 ListModel

c++ - C、Linux 中的串口读取/打开错误

c++ - 角拼接数据结构,任何开源实现?

c++ - 对指针的 const 引用可以改变对象