c++学习点滴6


一、构造函数

class NoName {
public:
	NoName();
	explicit NoName(const char *);
	NoName(const char *, int);
	NoName(const char *, int, double);
	NoName(const NoName&);

	virtual ~NoName();

protected:
	char *pstr;
	int ival;
	double dval;
private :
	void initNoName(const char *ps);
};

void NoName::initNoName(const char *ps) {
	if (ps) {
		pstr = new char[strlen(ps)+1];
		strcpy(pstr, ps);
	} else {
		pstr = new char[1];
		*pstr = '\0';
	}
}

NoName::NoName() {
	pstr = new char[1];
	*pstr = '\0';
	ival = 0;
	dval = 0;
}

NoName::NoName(const char *ps) {
	initNoName(ps);
	ival = 0;
	dval = 0;
}
NoName::NoName(const char *ps, int i) {
	initNoName(ps);
	ival = i;
	dval = 0;
}
NoName::NoName(const char *ps, int i, double d) {
	initNoName(ps);
	ival = i;
	dval = d;
}
NoName::NoName(const NoName &rhs) {
	initNoName(rhs.pstr);
	ival = rhs.ival;
	dval = rhs.dval;
}
NoName::~NoName() {
	delete pstr;
	pstr = 0;
	
}

使用带缺省值的构造函数:

class NoName {
public:
	NoName(const char *ps=0, int i =0, double d=0);
	NoName(const NoName&);

	virtual ~NoName();

protected:
	char *pstr;
	int ival;
	double dval;
private :
	void initNoName(const char *ps);
};

void NoName::initNoName(const char *ps) {
	if (ps) {
		pstr = new char[strlen(ps)+1];
		strcpy(pstr, ps);
	} else {
		pstr = new char[1];
		*pstr = '\0';
	}
}
NoName::NoName(const char *ps, int i, double d) {
	initNoName(ps);
	ival = i;
	dval = d;
}
NoName::NoName(const NoName &rhs) {
	initNoName(rhs.pstr);
	ival = rhs.ival;
	dval = rhs.dval;
}
NoName::~NoName() {
	if (pstr) {
		delete pstr;
		pstr = 0;
	}
}


二、初始化

// C++的数据成员中,只允许const static的数据成员在定义时被初始化
/*
class Test {
private:
	//int i = 0; // error
	//const int i = 0; // error
	//static int i = 0; // error
	const static int i = 0; // ok
};
*/

/*
class MyMember1  {
public :
	MyMember1(){}  // 有默认构造函数
};

class MyMember2 {
public :
	MyMember2(int i){}; // 没有默认构造器
};


// c++ 类的初始化分为隐式初始化、显示初始化、和计算部分(构造函数体内的所有语句)
// 隐式初始化包括: 1.调用所有父类的默认构造器  2.调用所有类成员的默认构造器
// 显示初始化,通过成员列表进行的初始化(推荐这样做)
// 计算部分,即位于构造器内部的所有语句
// 初始化顺序按照成员声明的顺序,而非初始化列表中的顺序。所以为了方便理解,我们要以成员声明的顺序去进行初始化
class MyClass {
public:
	MyClass(){} // 没有成员列表初始化
private :
	MyMember1 m1; // ok。能通过
	MyMember2 m2; // error。对于没有默认构造器的类成员,只能通过成员列表进行初始化
};
*/

/*
class MyMember1 {
public:
	MyMember1(int i){}
};
// 只能通过列表初始化的方式去初始化的情况:
// 1. const(非static)的成员
// 2. 引用成员
// 3. 没有默认构造函数的那些类成员
class MyClass {
public:
	MyClass() :i(100), ri(i), ci(200), m1(3){}
private:
	int i;
	int &ri;
	const int ci;
	MyMember1 m1;
};
*/


 

 三、extern关键字使用:

1. 在xx.cpp中定义函数和变量
int i10 = 10;

void fun(const char* str) {
	std::cout << "fun(): " << str << std::endl;
}

2. 在xx.h中用extern声明这些变量和函数
extern int i10;
extern void fun(const char* str);

3. 在别的yy.cpp中包含该xx.h头文件
#include "xx.h"
然后在yy.cpp中直接使用这些变量和函数
int main() {
	fun("allei");
	cout << "i10=" << i10 << endl;
	return 0;
}


 

 四、static关键字

1. static全局变量
  * 只能在本文件访问,对于其他文件不可见。其他文件中可以定义同名的变量而不会冲突。
   * 保存在全局数据区,默认初始化为0
   * 普通全局变量,可以通过extern在其他文件中引用

2. static 局部变量
   * 不会随着函数调用结束而释放,而是继续保留上次被调用的值。在全局数据区分配空间,在第一次调用时被初始化,后续调用不再进行初始化

3. static函数
  * 和普通函数的区别是只在本文件中可见,不能通过extern的方式被其他文件引用

4. class中的静态成员
  * 属于类而非类的对象


 

你可能感兴趣的:(c++学习点滴6)