// refer_value.cpp : 定义控制台应用程序的入口点。
//2011/10/5 by wallwind at sunrise
#include "stdafx.h"
#include <iostream>
using namespace std;
class Base
{
public:
Base(){cout<<"Base()"<<endl;}
~Base(){cout<<"~Base()"<<endl;}
private:
string str1;
string str2;
};
class Derived:public Base
{
public:
Derived(){cout<<"Derived()"<<endl;}
~Derived(){cout<<"~Derived()"<<endl;}
bool retTrue()
{
return true;
}
private:
string str1;
string str2;
};
bool validateDerived(Derived d)
{
return d.retTrue();
}
int _tmain(int argc, _TCHAR* argv[])
{
Derived d;
bool bb=validateDerived(d);
system("pause");
return 0;
}

bool retTrue() const
{
return true;
}
bool validateDerived(const Derived& d)
{
return d.retTrue();
}
运行的结果:

// refer_value.cpp : 定义控制台应用程序的入口点。
//2011/10/5 by wallwind at sunrise
#include "stdafx.h"
#include <iostream>
using namespace std;
class Window
{
public :
Window(){};
void name()const;
virtual void display()const;
};
void Window::name()const
{
cout<<"window name"<<endl;
}
void Window::display()const
{
cout<<" window display()"<<endl;
}
class WindowWithScrollBars:public Window{
public:
WindowWithScrollBars(){};
virtual void display() const;
};
void WindowWithScrollBars::display() const
{
cout<<"WindowWithScrollBars display()"<<endl;
}
void pintNaandWind(Window w)
{
w.name();
w.display();
}
int _tmain(int argc, _TCHAR* argv[])
{
WindowWithScrollBars wwsb;
pintNaandWind(wwsb);
return 0;
}
运行的结果如图所示:

void pintNaandWind(const Window& w)
{
w.name();
w.display();
}
运行结果得到:

解释一下:
(1)所谓的slicing问题,也就是如果你把子类的对象赋值给父类的对象,如果用reference和指针,当然是可以的,而且这也是virtual的实现必需品。但是,如果用pass-by-value,就会出现,传进去的总是父类的对象,在传递对象的时候出现了切割问题。
(2)如果窥视c++编译器的底层,你会发现,references往往以指针实现出来,因此pass-by-reference通常意味着这真正传递的是指针。因此如果你有个对象属于内置类型(如int),pass by reference或pass by reference to const时,选择pass by value并非没有道理。这个忠告也适用于STL的迭代器和函数对象,因为习惯上它们都被设计为pass by value。迭代器和函数对象的实践者有责任看看他们是否高效且不受切割问题的影响。
(3)内置类型都相当的小。因此有人认为,所有小类型的types都是pass by value的合格候选人,甚至他们是用户自定义的class亦然。这是个不可靠的推论。对象小并不就意味其copy构造函数不昂贵。许多对象,包括STL容器,内含的东西只比一个指针多一些,但复制这种东西对象却需要承担“复制那些指针的每一样东西”。那将非常昂贵。
即使小型对象拥有并不昂贵的copy构造函数,还是可能有效率上的争议。某些编译器对待“内置类型”和“用户自定义类型”的态度截然不同,总是两者有相同的底层表述。举个例子,某些编译器拒绝把只由一个double组成的对象放进缓存器内,却很乐意在一个正规基础上对光秃秃的double那么做。当这种事发生,你更应该以by reference方式传递此等对象,因为编译器当然会将指针(references的实现体)放进缓存器内,绝无问题。
小型的用户自定义类型并不必然成为pass by value优良候选人的另一个理由是,作为一个用户自定义类型,其大小容易有所改变。甚至当你改用另一个c++编译器都有可能改变type的大小。举个例子,某些标准程序库实现版本中的string类型比其他版本大七倍!
▲ 尽量以pass-by-reference-to-const替换pass-by-value.前者通常比较高效,并可避免切割问题(slicing
problem).
▲ 以上规则并不适合与内置类型,以及STL的迭代器和函数对象.对它们而言,pass-by-value往往比较适合.