C++学习笔记01:无指针类基本写法

哎,做了3年深度学习,到了科研院所,却从客户端开发做起,终究逃不过C++,底子太薄,重新学吧,学习的素材是侯捷的C++课。

C++相比C,最大的区别就是有class的概念,它将数据和函数包含在了一起,由类来创建对象

类之间最大的区别就是带指针和不带指针的

C++程序代码的基本形式:

头文件.h

主程序.cpp,要include头文件

标准库,也是.h,也需要在主程序中include

防卫式声明:

#ifndef __COMPLEX__
#define __COMPLEX__

...

#endif

防卫式声明可以理解成如果没有定义过这个头文件,那么就定义,代码在引用头文件时,最直观的理解就是看做把头文件中的代码拷过来

如果一个文件引用了两个头文件,而这两个头文件中其中一个也引用了另一个头文件,这样就会出现重复定义

防卫式声明的写法:
当然宏名无所谓(这里的__IOSTREAM__H),有就行,不需要与文件名或者类名相同,只要和别的防卫式声明不一样就行,但是最好还是见名知意,防止以后查代码的时候方便。大致的写法参照上面的就行了。

哎,昨天写了好多忘保存了

Template:

为了节省修改变量类型花费的时间,用template来创造模板,用一个新的符号只带数据类型,创建变量时写成新的符号+变量名,这样改变符号的定义就能改变数据类型

template <typename T>
class complex
{
public:
    complex(T r = 0, T i = 0): re(r), im(i){}
    complex& operator +=(const complex&);
    T real() const {return re;}
    T imag() const {return im;}
private:
    T re, im;
    friend complex& __doapl (complex*, const complex&); 
}

//使用时
{
    complex<double> c1(2.5,1.5);
    complex<int> c2(2,6);
}

函数模板:

template <class T>
inline
const T& min(const T& a, const T& b)
{
    return b < a ? b : a;
}

如果T不是基本数据类型,则编译器会去找T类有没有定义<符号的操作符重载

访问级别

public和private

构造函数:

class complex
{
public:
	complex(double r = 0, double i = 0) :re(r), im(i){ }; //这个:是构造函数特有的
//构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中
//的初始化式。

private:
	double re, im;
};

构造函数初始化列表以一个冒号开始,接着是以逗号分隔的数据成员列表,每个数据成员后面跟一个放在括号中的初始化式。

构造函数中要把初始化和赋值分开,这样写比较规范,不要写成

public:
	complex(double r = 0, double i = 0) { re = r; im = i; }

构造函数可以重载,但要注意,不要写多个具有相同数量的未初始化变量作为输入的构造函数,比如不能同时写下面的两个构造函数,因为两个没有初始化值的输入变量个数都是0

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

什么情况下构造函数放在private里

Singleton模式,即这个类只创建一个实例,这个实例在publick中的static A& getInstance();创建,外界只能通过A::getInstance()来访问A中的成分。

class A {
public:
    static A& getInstance( return a );
    setup() {...}
private:  //构造函数在private里,没有人能创建A类的object
    A();
    A(const A& rhs);
    static A a; //通过static创建了一个object,即使没人创建class A的object,只要有这行代码,就
                //会有一个class A的object
    ...
};

上面的结果就是只有属于A类的object只有一个a,而且外界也只能通过getInstance来访问

如果不想一开始就有个属于A类的a,万一一直没用会浪费空间,则写成下面这种形式

class A {
public:
    static A& getInstance( return a );
    setup() {...}
private:  //构造函数在private里,没有人能创建A类的object
    A();
    A(const A& rhs);
    ... // 这里没有static A a;了
};

A& A::getInstance()  //只有有人调用这个函数,才会创建一个A类的a
{
    static A a;
    return a;
}

const

double real() const { return re; }  // real()函数的功能仅是返回实部
double imag() const { return im; }

对于不会改变数据内容的函数,要加上const

const也可以出现在对象和变量的前面,也是表示它们的内容不会改变

如果使用者在使用这个对象时加了const,而这个对象在定义时没有加const,会产生矛盾,报错,使用时可以选择加不加const,但定义时一定要加

参数传递

complex(double r = 0, double i = 0) // pass by value 传的就是值,压倒栈里
    :re(r), im(i){ }; 
complex& operator += (const complex&); // pass by reference 传的是地址,4bit,像个指针
// pass by reference 也分带const和不带const的,参数传递尽量用这种形式,除非参数的类型本身就是char这类的,另外函数中的临时对象不能以reference的形式传出去,不然函数一结束,这个临时对象就找不到的
complex& operator += (const complex&); //返回值也分return by value和return by reference(to const)

只要函数的结果不是传给一个local object,结果就可以通过reference传递

friend友元

将全局函数声明为友元的写法如下:
friend  返回值类型  函数名(参数表);

将其他类的成员函数声明为友元的写法如下:
friend  返回值类型  其他类的类名::成员函数名(参数表);

被声明成friend的函数可以直接调用private里的元素

private:
	double re, im;
	friend complex& __doapl(complex *, const complex&);  //注意friend
....

inline complex&
__doapl(complex * ths, const complex& r)
{
	ths->re += r.re;  //这里直接拿取了re,而不是通过public下的re()函数
	ths->im += r.im;
	return *ths;
}

相同class的各个object互为友元,意思是如果一个class中有一个函数是用来处理传入的参数为同一个class的一个实例时,这个函数可以直接对这个class中的private中的元素操作,比如在complex类中的public中声明如下代码:

int func(const complex& param)
{return param.re + param.im;}  // 注意这里re和im都不是函数,而是complex中private中的变量

内联函数inline

是一种请求,是inline的会很快、很好,由编译器最后决定是否inline。函数在class本体里定义定义完成,就是有inline请求的,不用写inline。在函数体外面也可以请求inline,方法就是加上inline。

double real() const { return re; }//有花括号,属于类的定义,是内联函数

inline complex&
__doapl(complex * ths, const complex& r)
{
	ths->re += r.re;  //这里直接拿取了re,而不是通过public下的re()函数
	ths->im += r.im;
	return *ths;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值