函数重载不可以根据返回类型区分??
在c++primer上,有段代码根据对象是否是const重载了一个函数,结果我写的时候发现仅仅根据函数返回类型无法重载函数,这都什么情况
C++primer上的
程序代码:
//根据对象是否为const重载了display函数 Screen &display( std::ostream &os ){ do_display(os); return *this; } //无法重载仅按返回类型区分的函数??? const Screen &display(std::ostream &os) { do_display(os); return *this; }
完整的
#include <iostream>
#include <string>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std ;
class Screen {
public:
using pos = string::size_type ;
//C++,已经提供了一个构造函数,所以编译器不会自动生成默认构造函数,
//可以使用=default告诉编译器生成默认的构造函数
Screen() = default ; //因为Screen有另一个构造函数,所以本函数是必须的
Screen(pos ht, pos wd) : height(ht), width(wd) { }
Screen( pos ht, pos wd, char c ): height( ht ), width( wd ),
contents( ht*wd, c ) { }
//定义在类内部的成员函数自动inline
char get( ) const{//读取光标处字符
return contents[cursor];//隐式内联
}
//重载get函数
inline char get(pos ht, pos wd) const;//显式内联
Screen &move(pos r, pos c) ;
Screen &set(char) ;
Screen &set( pos, pos, char ) ;
void some_member( ) const ;
//根据对象是否为const重载了display函数
Screen &display( std::ostream &os ){
do_display(os); return *this;
}
//无法重载仅按返回类型区分的函数???
const Screen &display(std::ostream &os) {
do_display(os); return *this;
}
private:
pos cursor = 0 ;
pos height = 0, width = 0;
string contents ;
//const成员函数也可以修改可变数据成员
mutable size_t access_ctr ;//即使在一个const对象内也能被修改
void do_display(std::ostream &os) const { os << contents; }
};
inline Screen &Screen::move( pos r, pos c ) { //可以在函数的定义处指定inline
pos row = r*width ; //计算行的位置
cursor = row + c ; //在行内将光标移动到指定列
return *this ; //以左值的形式返回对象
}
char Screen::get ( pos r, pos c ) const//在类的内部声明成inline
{
pos row = r*width ;//计算行的位置
return contents[ row + c ] ;//返回给定列的字符
}
void Screen::some_member() const {
//记录成员函数被调用的次数
++access_ctr ;
}
class Window_mgr {
private:
//这个Window_mgr追踪Screen
//默认情况下,一个Window_mgr包含一个标准尺寸的空白Screen
vector<Screen> screens{ Screen{ 24 , 80 , ' '} } ;
};
inline Screen &Screen::set(char c) {
contents[cursor] = c ; //设置当前光标所在位置的新值
return *this ; //将this对象作为左值返回
}
inline Screen &Screen::set( pos r , pos col ,char ch ) {
contents[ r*width + col ] = ch ; //设置当前光标所在位置的新值
return *this; //将this对象作为左值返回
}
int main() {
Screen myscreen ;
char ch = myscreen.get();//调用Screen::get( )
ch = myscreen.get(0, 0);//调用Screen::get( pos , pos )
Screen myScreen;
//返回引用的函数是左值的,意味着返回的是对象本身而非对象副本
//把光标移动到一个指定的位置,然后设置该位置的字符值
myScreen.move(4, 0).set('#') ;
//上面的语句等价于
myScreen.move( 4, 0 ) ;
myScreen.set( '#' ) ;
//如果令move和set返回Screen而非Screen& 则上面的语句等价于
Screen temp = myScreen.move(4, 0) ;//对返回值进行拷贝
temp.set( '#' ) ;//不会改变myScreen的contents
Screen myscreen(5, 3) ;
const Screen blank(5, 3);
myscreen.set('#').display(cout);//调用非常量版本
blank.display(cout);//调用常量版本
return 0;
}
#include <string>
#include <stdio.h>
#include <string>
#include <vector>
using namespace std ;
class Screen {
public:
using pos = string::size_type ;
//C++,已经提供了一个构造函数,所以编译器不会自动生成默认构造函数,
//可以使用=default告诉编译器生成默认的构造函数
Screen() = default ; //因为Screen有另一个构造函数,所以本函数是必须的
Screen(pos ht, pos wd) : height(ht), width(wd) { }
Screen( pos ht, pos wd, char c ): height( ht ), width( wd ),
contents( ht*wd, c ) { }
//定义在类内部的成员函数自动inline
char get( ) const{//读取光标处字符
return contents[cursor];//隐式内联
}
//重载get函数
inline char get(pos ht, pos wd) const;//显式内联
Screen &move(pos r, pos c) ;
Screen &set(char) ;
Screen &set( pos, pos, char ) ;
void some_member( ) const ;
//根据对象是否为const重载了display函数
Screen &display( std::ostream &os ){
do_display(os); return *this;
}
//无法重载仅按返回类型区分的函数???
const Screen &display(std::ostream &os) {
do_display(os); return *this;
}
private:
pos cursor = 0 ;
pos height = 0, width = 0;
string contents ;
//const成员函数也可以修改可变数据成员
mutable size_t access_ctr ;//即使在一个const对象内也能被修改
void do_display(std::ostream &os) const { os << contents; }
};
inline Screen &Screen::move( pos r, pos c ) { //可以在函数的定义处指定inline
pos row = r*width ; //计算行的位置
cursor = row + c ; //在行内将光标移动到指定列
return *this ; //以左值的形式返回对象
}
char Screen::get ( pos r, pos c ) const//在类的内部声明成inline
{
pos row = r*width ;//计算行的位置
return contents[ row + c ] ;//返回给定列的字符
}
void Screen::some_member() const {
//记录成员函数被调用的次数
++access_ctr ;
}
class Window_mgr {
private:
//这个Window_mgr追踪Screen
//默认情况下,一个Window_mgr包含一个标准尺寸的空白Screen
vector<Screen> screens{ Screen{ 24 , 80 , ' '} } ;
};
inline Screen &Screen::set(char c) {
contents[cursor] = c ; //设置当前光标所在位置的新值
return *this ; //将this对象作为左值返回
}
inline Screen &Screen::set( pos r , pos col ,char ch ) {
contents[ r*width + col ] = ch ; //设置当前光标所在位置的新值
return *this; //将this对象作为左值返回
}
int main() {
Screen myscreen ;
char ch = myscreen.get();//调用Screen::get( )
ch = myscreen.get(0, 0);//调用Screen::get( pos , pos )
Screen myScreen;
//返回引用的函数是左值的,意味着返回的是对象本身而非对象副本
//把光标移动到一个指定的位置,然后设置该位置的字符值
myScreen.move(4, 0).set('#') ;
//上面的语句等价于
myScreen.move( 4, 0 ) ;
myScreen.set( '#' ) ;
//如果令move和set返回Screen而非Screen& 则上面的语句等价于
Screen temp = myScreen.move(4, 0) ;//对返回值进行拷贝
temp.set( '#' ) ;//不会改变myScreen的contents
Screen myscreen(5, 3) ;
const Screen blank(5, 3);
myscreen.set('#').display(cout);//调用非常量版本
blank.display(cout);//调用常量版本
return 0;
}