C++学习笔记(二)

构造函数的初始化

class A{
private:
	int i = 10;
	int j = 20;
	int k = t(i);
public:
	A() : k(12){
		cout << "i = " << i << " j = " << j << " k = " << k << endl;
	}
	int t(int i){
		cout << "func t() " << endl;
		return (i + 13);
	}
	
};

int main(){
	A a;
	return 0;
}
// out
// i = 10 j = 20 k = 12
class A{
private:
	int i = 10;
	int j = 20;
	int k = t(i);
public:
	A() : i(12){
		cout << "i = " << i << " j = " << j << " k = " << k << endl;
	}
	int t(int i){
		cout << "func t() " << endl;
		return (i + 13);
	}
	
};
// out
// func t() 
// i = 12 j = 20 k = 25

构造函数的初始化列表的执行先于构造函数,同样初始化列表的优先级先于定义初始化。

class B{
private:
	int i;
public:
	B(int j): i(j){
		cout << "B() " << j << endl;
	}

};

class A{
private:
	B b1, b2;
public:
	A() : b2(1), b1(2){
	}
	int t(int i){
		cout << "func t() " << endl;
		return (i + 13);
	}
	
};
// out
// B() 2
// B() 1

构造函数的执行顺序是成员变量的书写顺序而不是初始化列表的书写顺序。

class A{
private:
	int i;
	string s;
public:
	A(int i) : s("hello"){}
	A(){
		s = "hello";
	}

相比之下,第二种的效率更低,原因是程序在执行的时候首先需要构造出一个空白的string类,之后再把它赋值为“hello”,而前一种则直接调用string类的构造器完成构造。

#include <iostream>
#include <string>
#include <ctime>
using namespace std;

class A{
private:
	string s;
public:
	A() :  s("hello"){}
	A(int i){
		s = "hello";
	}
};

int main(){
	clock_t begin1 = clock();
	for(int i = 0; i < 100; i++){
		A a1;
	}
	clock_t end1 = clock();
	clock_t begin2 = clock();
	for(int i = 0; i < 100; i++){
		A a2(1);
	}
	clock_t end2 = clock();

	cout << "first: " << end1 - begin1 << "ms" << endl;
	cout << "second: " << end2 - begin2 << "ms" << endl;
	return 0;
}

// out
// first: 16ms
//  second: 7ms

Overloading

函数重载的条件是参数不一样,注意返回值不同无法区分两个函数。
对于函数的默认参数值,如果在“.h”文件中已经声明,那么在“.cpp”文件中不能再次声明。其实默认参数值并非函数本身实现的,而是编译器在编译程序的时候实现的。

inline

内联函数是declaration不是definition,因此inline函数必须写在头文件里。
一般而言,较短的函数适合改编为内联函数,较长的函数或者循环较多的函数不适合设计成内联函数。其实,一些编译器可以自动识别函数是否值得改写为内联函数。

const

char * const q = "abc";	// Pointer q is a const.
q = 'c';	// OK
q++;		// ERROR

const char * q = "abc";	// Contect that q points to is a const.
q = 'c';	// ERROR

const char * q = "abc";
// It means that we couldn't change "abc" via q, while "abc" is changable.

const与成员函数

在代码和头文件里都需要声明const成员函数

class Date{
private:
	int day;
public:
	void set_day();
	const int get_day();
}
void Date::set_day(int d){
	day = d;
}
int Date::get_day() const{
	day++	// Valid to change memble value.
	set_day(1)	// Valid to call a non-const memble function
	return day;
}

注意const和非const的函数是可以overload的,因为在c++语法糖中每一个成员函数都有一个隐藏的指针参数,const是修饰该参数的。
如果一个类有一个const的成员变量,那么需要在构造函数的初始化列表里或者定义初始化中完成初始化。

static

一个静态的成员变量需要在类里面声明是static(.h文件)在代码文件里再加一个定义(不能在此加static)(.cpp文件)。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值