C++常用特性笔记


以下内容为本人学习笔记,不足之处请指出,后期会不断完善。
#访问权限:

  • public 公共接口 :向外界开放,可通过对象或类名访问
  • protected 受保护的访问:类内可以访问 ,不可通过对象访问,可以被派生类访问,不能被用户代码(类外)访问。主要作用是来实现类的一个特征就是继承
  • private私有 :只能由类成员(类内)和友元访问,外界不可以通过任何形式访问
    #继承关系:
  • public继承是is-a的关系,可以用父类的指针或者引用指向子类的对象,适用于基类身上的每一件事情一定适用于派生类身上,因为每一个派生对象也都是基类对象;
  • protected和private继承没有is-a的关系,只是has-a的关系,表示“组合”或者“拥有”的关系,不可以用父类的指针或引用指向子类对象。
  • C++对象模型中,子类对象的内存空间中包含父类的部分,当用父类指针指向一个子类的对象实时,这个指针可以访问的是相应的父类那部分的内存;在 protected和private继承的情况下,父类的内存部分是私有的,不对外开放的,所以,protected和private继承时,不可以用父类的指针或引用指向子类对象。

#类的静态数据成员

  • 使用static关键字声明
  • 为该类的所有对象共享,静态数据成员具有静态生存期。
  • 必须在类外定义和初始化,用(::)来指明所属的类。
    例子:
#include <iostream>
using namespace std;
class Point{
public :
	Point(int x=0,int y=0):x(x),y(x){//构造函数
		count++;
	}
	Point(Point &p){//复制构造函数
		x=p.x;
		y=p.y;
		count++;
	}
	~Point(){count--}
	int getX(){return x;}
	int getY(){return y;}
	void showcount(){
		count<<"Object count = "<<count<<endl;
	}
private:
	int x,y;
	static int count;//静态数据成员的声明
};
int Ponit::count = 0;//静态数据成员定义与初始化
int main(){
	Point a(4,5);
	cout <<"Point A:"<<a.getX()<<","<<a.getY()<<endl;
	a.showCount();
	
	Point b(a);
	cout <<"Point B:"<<b.getX()<<","<<b.getY()<<endl;
	b.showCount();
	return 0;
}

输出结果:
Point A:4,5 Object count=1
Point B:4,5 Object count=2

数据保护

常类型

常对象

  • 必须进行初始化,不能被更新。
  • 定义:类名 const 对象名(实参列表);或 const 类名 对象名(实参列表);
  • 如果一个对象被声明为常对象,则不能调用该对象的非const型的成员函数(除了由系统自动调用的隐式构造函数和析构函数)。否则就会报错。

常成员

  • 用const进行修饰的类成员:常数据成员(只能通过构造函数的参数初始化表对常数据成员进行初始化)和常函数成员(专门用来处理常对象的,声明和定义处都要写const)。
    例子:常数据成员
#include <iostream>
using namespace std;
class A{
public :
	A(int i);
	void print();
private:
	const int a;
	static const int b;//静态常成员函数(类中是共享的)
};
const int A::b=10;
A::A(int i):a(i){}
void A::print(){
	cout<<a<<":"<<b<<endl;
}
Int main(){
	//建立对象a和b,并以100和0作为初值,分别调用构造函数,
	//通过构造函数的初始化列表给对象的常数据成员赋初值
	A a1(100),a2(0);
	a1.print();
	a2.print();
	return 0
}

运行结果:
100:10
0:10
例子:常函数成员

#include <iostream>
using namespace std;
class R{
public:
	R(int r1,int,r2):r1(r1),r2(r2){}
	void print();
	void print() const;
private:
	int r1,r2;
};
void R::printf(){
	cout<<r1<<":"<<r2<<endl;
}
void R::printf() const {
	cout<<r1<<":"<<r2<<endl;
}
int main(){
	R a(4,5);
	a.print();//void print()
	const R b(20,54);
	b.print();//void print() const
	return 0;
}

常引用

  • 被引用的对象不能被更新,不能修改。
  • 定义 const 类型说明符 &引用名;
    例子:
#include <iostream>
#include <cmath>
class Point{
public :
	Point(int x=0,int y=0):x(x),y(x){}
	int getX(){return x;}
	int getY(){return y;}
	friend float dist(const Point &a,const Point &b);
private:
	int x,y;
};
float dist(const Point &a,const Point &b){
	double x=a.x-b.x;
	double y=a.y-b.y;
	float static_cast<float>(sqrt(x*x+y*y));
}
int main(){
	Point p1(1,1),p2(3,5);
	cout <<dist(p1,p2)<<endl;
}

常数组

  • 数组元素不能被更新。
  • 定义: 类型说明符 const 数组名[大小];

常指针

  • 指向常量的指针。

类的友元

  • 友元是C++提供的一种破坏数据封装和数据隐藏的机制。
  • 通过将一个模块声明为另一个模块的友元,一个模块能够引用到另一个模块中本是被隐藏的信息。
  • 可以声明友元函数和友元类
  • 为了确保数据的完整性,及数据封装与隐藏的原则,建议慎用友元。

友元函数

  • 友元函数是在类声明中由关键字friend修怖说明的非成员函数,在它的函数体中能够通过对象名访问private和protected成员,
  • 作用:增加灵活性,使程序员可以在封装和快速性方面做合理选择。
  • 访问对象中的成员必须通过对象名。
#include <iostream>
#include <cmath>
class Point{
public :
	Point(int x=0,int y=0):x(x),y(x){}
	int getX(){return x;}
	int getY(){return y;}
	friend float dist(Point &a,Point &b);
private:
	int x,y;
};
float dist(Point &a,Point &b){
	double x=a.x-b.x;
	double y=a.y-b.y;
	float static_cast<float>(sqrt(x*x+y*y));
}
int main(){
	Point p1(1,1),p2(3,5);
	cout <<dist(p1,p2)<<endl;
}

友元类

  • 若一个类为另一个类的友元,则此类的所有成员都能访问对方类的私有成员。
  • 声明语法:将友元类名在另一个类中使用friend修饰说明。
    例如:
class A {
	friend class B;
	public:
	void display() {
		cout << x <<endl.
	}
private:
	int x ;
};
class B {
public:
	void set(int i);
	void display();
private:
	A a;
};
void B::set(int i) {
	a.x=i;
}
void B::display() {
	a.display();
}

例子2:

class Point{
class Point{
public :
	Point(int x=0,int y=0):x(x),y(x){}
	int getX(){return x;}
	int getY(){return y;}
	friend QDebug& operator<<(Qdebug &debug,const Point &point);//运算操作符重载
private:
	int x,y;
}
QDebug& operator<<(Qdebug &debug,const Point &point){
	return debug<<Qsting("[%1,%2]").arg(point.x).arg(point.y);
}
int main(){
	Qapplication app(argc,argv);
	Qlist<Point> points;
	points<<Point(1,2)<<Point(2,3);
	qDebug<<points;
	return 0;
}

多态性

实现类动态多态性,需要声明函数为虚函数,这样就可以实现使用基类指针来访问不同的派生类实例函数。

#include <iostream>
using namespace std ;
class Basel { 
public: 
	virtual void display() const; //虚函数
}; 
void Basel::display() const { 
	cout << "Basel: display()" << endl 
}

class Base2::public Base1 { 
public: 
	virtual void display() const; //虚函数
}; 
void Base2::display() const { 
	cout << "Base2: display()" << endl 
}

class Derived::public Base2 { 
public: 
	virtual void display() const; //虚函数
}; 
void Derived::display() const { 
	cout << "Derived: display()" << endl 
}
void fun(Base1 *ptr){
	ptr->display();
}

int main(){
	Base1 base1;
	Base2 base2;
	Derived derived;
	fun(&base1);
	fun(&base2;
	fun(&derived);
	return 0;
}

运行结果为:
Basel: display()
Base2: display()
Derived: display()
这样就达到了使用基类指针访问进程类函数的目的,如果不添加虚函数,则运行的结果为:
Basel: display()
Basel: display()
Basel: display()

纯虚函数

  • 纯虚函数是一个在基类中声明的虚函数,它在该基类中没有定文具体的操作内容,要求各派生类根据实际需要定义自己的版本,纯虚函数的声明格式为:
  • 定义: virtual 函数类型 函数名(参数表)=0;

抽象类:

  • 定义
class 类名{
	virtual 函数类型 函数名(参数表)=0;
	//其他成员。。。
}
  • 抽象类作用
    • 将有关的数据和行为组织在一个继承层次结构中,保证派生类具有要求的行为。
    • 对于暂时无法实现的函数,可以声明为纯虚函数,留给派生类去实现。
  • 注意
    抽象类只能作为基类来使用,不能定义抽象类的对象。

单例模式

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值