`

条款19: 分清成员函数,非成员函数和友元函数

阅读更多
条款19: 分清成员函数,非成员函数和友元函数
很前几章一样,先提供一个类的代码
//伪代码
class rational {
public:
  rational(int numerator = 0, int denominator = 1);
  int numerator() const;
  int denominator() const;

  const rational operator*(const rational& rhs) const;
private:
  ...
};

class rational //有理数
{
public:
	rational(int numerator = 0, int denominator = 1);
	rational& operator=(const rational& rhs);
	const rational operator*(const rational& rhs);

	void print();

	int getX()const;
	int getY()const;
private:
	int x;
	int y;
};
int rational::getX()const 
{
	return x;
}

int rational::getY()const
{
	return y;
}

const rational operator*(const rational &r1, const rational &r2)
{
	return rational( r1.getX()*r2.getX(), r1.getY()*r2.getY() );
}

void rational::print()
{
	cout<<"x= "<<x
		<<"y= "<<y<<endl;
}

rational::rational(int numerator , int denominator ):x(numerator), y(denominator)
{
}

rational& rational::operator =(const rational &rhs)
{
	if(this==&rhs)
		return *this;

	x=rhs.x;
	y=rhs.y;
	return *this;
}

const rational rational::operator*(const rational& rhs)
{
	rational r;
	r.x=x*rhs.x;
	r.y=y*rhs.y;
	return r;
}


int main()
{
	rational r1(5,10);
	rational r2(50,100);
	rational r3;
	r3=2*r2;
	r3.print();

	system("pause");
	return 0;
}

进行运算符的操作
rational oneeighth(1,;
rational onehalf(1, 2);

rational result = onehalf * oneeighth;   // 运行良好
result = result * oneeighth;             // 运行良好

result = onehalf.operator*(2);      // 运行良好----->> result = onehalf * 2;
result = 2.operator*(onehalf);      // 出错!   ----->> result = 2 * onehalf;

这里有两个知识点,在result = 2.operator*(onehalf);result = 2 * onehalf;即这种中因为2没有这样的函数所以导致调用

出错(或者说对函数列表中非*this指针对对应的对象进行转换)。在此期间,编译器还会尝试调用result = operator*(2,

onehalf); 这样的一个非成员函数(在导入的命名空间内寻找)

result = onehalf.operator*(2); 为什么会通过?
这实际上被隐式转换了
const rational temp(2);
result = onehalf * temp;     // 同onehalf.operator*(temp);

为什么有这种转换呢?涉及到explicit关键字,如果这样申明那么就禁止转换而报错了
explicit rational(int numerator = 0,     // 此构造函数为
                    int denominator = 1);  // explicit

explicit adj.外在的, 清楚的, 直率的, (租金等)直接付款的

那怎么解决呢?既然onehalf.operator*(2);这样能隐式转换,那么也希望2.operator*(onehalf)也能进行转换。但是因为函数

只对非*this对象进行转换所以如果单单依靠对象来带动函数的话是不太可能了。
effective解决的方法为设个和类名一样的空间,但是不提倡友元函数。
1
0
分享到:
评论

相关推荐

    实验二:友元和函数重载

    1. 友元的使用。 2. 掌握重载函数的实现方法。 3. 综合应用。

    C++友元成员函数使用实例

    C++友元函数的使用,这个友元函数是另一个类的成员函数

    C++之友元:友元函数和友元类详解

    一、友元介绍我们知道,类的成员函数可以访问同类的其他成员函数,包括公有、私有和保护成员。而类的外部函数只能访问类的公有成员。友元是一种允许非类成员函数访问类的非公有成员的一种机制。可以把一个函数指定为...

    友元类,友元函数,友元成员函数

    把谭书上的例子写了一下,有空就看看。从例子中就可以看出它的一些原理。

    运算符重载:友元(friend)函数问题

    运算符重载:友元(friend)函数问题

    Effective.C++.中文第二版.50条款doc文档.chm

    条款19: 分清成员函数,非成员函数和友元函数 条款20: 避免public接口出现数据成员 条款21: 尽可能使用const 条款22: 尽量用“传引用”而不用“传值” 条款23: 必须返回一个对象时不要试图返回一个引用 条款24: 在...

    友元成员函数

    本程序是使用友元成员函数的一个典型例子,简单、实用,对于初学者很有帮助。

    C++非静态成员函数完全可以作为线程函数

    一般地,线程要读写类的私有成员变量,只有两种方法:将全局函数声明为类友元friend,或者使用静态的成员函数static。那非静态的成员函数呢?一般地方都说的是,不行,做不了。。。为什么不行?都是代码区的代码,...

    友元机制计算两点之间的距离

    设计一个点(Point)类,其中包括一对坐标数据成员、一个求两点之间距离的友元接口和显示坐标点的成员函数,并用数据进行测试。 (2)程序设计说明 ① 在头文件中声明类,在源文件中定义类的成员函数,采用构造函数...

    成员函数做友元函数.zip

    成员函数做友元函数

    友元函数代码实例

    友元函数,类外普通函数声明为类的友元,之后即可与类共享数据

    友元函数和友元类_友元函数用法_

    私有成员只能在类的成员函数内部访问,如果想在别处访问对象的私有成员,只能通过类提供的接口(成员函数)间接地进行。这固然能够带来数据隐藏的好处,利于将来程序的扩充,但也会增加程序书写的麻烦。

    Effective C++

    条款19:分清成员函数,非成员函数和友元函数 条款20:避免PUBLIC接口出现数据成员 条款21:尽可能使用CONST 条款22:尽量用传引用而不用传值 条款23:必须返回一个对象时不要试图返回一个引用 条款24:在函数重载与设定...

    友元函数详细讲解

    友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。...通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。

    C++运算符重载函数作为类成员函数和友元函数.doc

    C++运算符重载函数作为类成员函数和友元函数.doc

    c++友元函数与友元类的深入解析

    非成员函数可以访问类中的公有成员,但是如果将数据成员都定义为公有的,这又破坏了隐藏的特性。另外,应该看到在某些情况下,特别是在对某些成员函数多次调用时,由于参数传递,类型检查和安全性检查等都需要时间...

    C++运算符重载 成员函数与友元函数详解

    以下是对C++运算符重载 成员函数与友元函数进行了介绍,需要的朋友可以过来参考下

    NDK14_C++基础:友元,模板方法,模板类,类型转换

    一 友元 类似 java 中享元模式:实例的共享(ImageLoader Lru 算法 存储图片) 友元:类或函数的共享 优点:提高效率、表达清晰 缺点:破坏封装性 ...友元函数不能被派生类继承 ...友元函数不能使用this

    编写一个友元函数,求两个日期之间相差的天数;

    日期类Date包含日期的年、月、日三个数数据成员,编写一个友元函数,求两个日期之间相差的天数; 重要的是理顺:这个函数不是Date类的成员函数

Global site tag (gtag.js) - Google Analytics