C++面向对象:complex类

随侯捷老师的课程学习C++面向对象。
第一部分是complex类的编写,老师通过例子培养标准大气的编程习惯,总结如下:

1.类定义的防卫

在头文件中用 #ifndef xxx #define xxx #endif 包住整个类定义部分,作为一个“防卫”方法。防止client多次include我们编写类的头文件。

2.public和private

类中我们不希望外界直接访问,仅想要类内访问的放到private里面,一般包括所有的变量。大部分函数(接口)放到public供外界访问。

3.函数声明

声明一个函数时要思考几个方面:
(1)参数。每一个参数,优先考虑使用引用的方式提高效率。 引用在C++的内部实现其实就是指向变量的指针常量(T* const),即指针不可变,但指向的值可以变化。因此引用传递(地址传递)通常比值传递效率更高。其次考虑函数中是否会改变该参数,不希望改变就加const。 假如不加const,编译器会认为该函数会改变此参数,这时若我们传入const常量,会报错。
(2)返回值。优先考虑用引用接收。 此处需要判断,若返回的值是函数内新创建的,则函数结束后该值生命周期结束,其引用也没有意义,因此此时必须用值传递的方式接收。若希望返回值不可修改,可加const。
(3)函数本身。只有类的非静态成员函数可以加const,即若该成员函数不改变类内成员变量,函数名后加const,为readonly,除非该变量被mutable修饰。此外,对于简单的函数,希望实现为inline

4.运算符重载

类的运算符重载有两种实现方式。
(1)类内成员函数。作为类内成员函数时,有一个隐含的参数this,就是该类本身。运算就是将右参数加(减乘除等)到左参数(this)上。
(2)类外函数。
考虑函数返回值时需要考虑用户连续使用运算符的情况。

5.模板类和友元函数

模板类在类定义前加template<typename T>,函数实现时前面也要加template<typename T>。
友元函数作为类外函数,但可以访问类内成员变量,可以在类内进行定义。

6.遇到的问题

(1)cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
原因是构造函数传入参数为非const引用。

complex(T& r = 0, T& i = 0) : re(r), im(i) {}

在以下代码创建complex对象时,传入的参数为临时计算结果,是常量。常量无法作为非const引用类型的参数传入,因此报出以上错误。原因是编译器认为函数会改变r和i的值,而不允许参数r和i为常数(const)。

template<typename T>
inline complex<T>
operator + (const complex<T>& x, const complex<T>& y)
{
    return complex<T>(real(x) + real(y), imag(x) + imag(y));
}

解决方法是将构造函数改为:

complex(T r = 0, T i = 0) : re(r), im(i) {}

或:

complex(const T& r = 0, const T& i = 0) : re(r), im(i) {}

(2)friend declaration … declares a non-template function
原因是友元函数声明的问题。将在类内的声明:

friend complex<T>& __doapl(complex<T>*, const complex<T>&);

改为:

template<typename U>
friend complex<U>& __doapl(complex<U>*, const complex<U>&);

可以解决问题。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值