C++类 简单总结

类的结构
类的定义
c语言中的struct是数据成员的集合 而c++中的类则是数据成员(属性)和成员函数 (服务)的集合 然而类的意义远不这样简单 定义类的目的是为了把现实世界中的事物 分类研究 类是对是事物的抽象描述 类的实体是对象
一般形式
class 类名
{
private:
数据成员和成员变量
protected:
··
public:
··
}
其中class是定义类的关键字
类名是用户为类起的名字
类名是用户为类起的名字 是c++的合法标识符 类名后花括号内 是类的说明部分 包括类的数据成员(属性) 和成员函数 (服务行为 或功能 )有三种不同性质的数据成员和成员函数 私有成员只能被 本类定义的成员函数所访问 类的公有成员可以被外部不属于该类的程序访问 公有成员多为成员函数 用来提供与外界的接口

#include<stdio.h>
#include<iostream>
using namespace std;
class MyClass
{
public:
	MyClass();
	~MyClass();
	void int_counter(void);
	void inc(void);
	void dec(void);
	int getvalue(void);

private:
	unsigned int value;

};

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}

研究这个类的内容
counter 名字
value 私有的
public 对外的接口
通常公有部分不定义变量 类以外的代码不能直接访问类的私有数据 这是一种实现封装的办法 封装可以严格控制对数据的访问
这些类的成员函数 也称为类的方法 前者是c++的术语 后者是面向对象方法中的术语
在类的定义中 可以只给出成员函数的原型函数的具体定义可以在类的定义之内给出也可以在类的定义之外给出 完成了类的定义之后 就等于建立了一个新的数据类型
类成员函数的定义
在类定义中说明成员函数的同时定义成员函数 与一般的定义函数没有什么区别

#include<stdio.h>
#include<iostream>
using namespace std;
class MyClass
{
public:
	MyClass();
	~MyClass();
	void int_counter(void);
	void inc(void);
	void dec(void);
	int getvalue(void)
	{
		return value;
	}

private:
	unsigned int value;

};

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}

如果是在类定义之外定义成员函数由于不同类的成员函数可能有相同的名字 因此在定义成员函数时要指明该函数是属于哪个类的 说明的方法是 在函数名与类名之间插入一个作用域区分符 ::
成员函数定义的一般形式为
函数类型 类名::函数名(参数 )
{
函数体
}

#include<stdio.h>
#include<iostream>
using namespace std;
class MyClass
{
public:
	MyClass();
	~MyClass();
	void int_counter(void);
	void inc(void);
	void dec(void);
	int getvalue(void)
	{
		return value;
	}

private:
	unsigned int value;

};

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}
void MyClass::int_counter(void)
{
	value=0;
}
void MyClass::inc(void)
{
	value += 1;
}
void MyClass::dec(void)
{
	value -= 1;
}
int MyClass::getvalue(void)
{
	return value;
}

类的对象定义 与访问
1定义对象
雷氏对象的抽象描述 对象是类的具体实例 (instance) 因此在定义了类之后 就可以像定义 int float 等类型变量那样去建立类的对象 可以使用 以下两种定义对象的方法
class 类名 对象名;

类名 对象名;
定义类的对象
例子:counter类
counter counter1 ;
或class counter counter1;
第二种方法
class 类名
{
}对象名;
定义对象数组
可以向其他数据类型一样 定义对象数组
counter counter a [10];
3访问对象成员
当定义了一个类的对象后 就可以访问对象的成员了 访问对象成员可以用成员选择符 .
访问对象的数据成员时 其形式为
对象名.数据成员
对象名.函数成员
对象的工作是 靠消息激活的 向对象发消息的方法就是调用成员函数

#include<stdio.h>
#include<iostream>
using namespace std;
class MyClass
{
public:
	MyClass();
	~MyClass();
	void init_counter(void);
	void inc(void);
	void dec(void);
	int getvalue(void)
	{
		return value;
	}

private:
	unsigned int value;

};

MyClass::MyClass()
{
}

MyClass::~MyClass()
{
}
void MyClass::init_counter(void)
{
	value=0;
}
void MyClass::inc(void)
{
	value += 1;
}
void MyClass::dec(void)
{
	value -= 1;
}

int main()
{
	MyClass counter1,counter2;
	counter1.init_counter();
	counter2.init_counter();
	counter1.inc();
	counter2.dec();
	cout<<counter1.getvalue()<<":is c1   c2 is: "<<counter2.getvalue()<<endl;
	return 0;
}

应用对象数组的例子

#include<stdio.h>
#include<iostream>
using namespace std;
class num
{
public:
	void set_ij(int x) { i = x; j = x + 1; }
	void out_i()
	{
		cout << i;
	}
	void out_j()
	{
		cout << j;
	}
	num();
	~num();

private:
	int i, j;
};

num::num()
{
}

num::~num()
{
}
int main()
{
	num a1[5], a2[5];
	for (int k= 0; k < 5; k++)
	{
		a1[k].set_ij(k);
	}
	for (int k = 0; k < 5; k++)
	{
		a2[k] = a1[k];
		cout << " a2[" << k << "].i=";
		a2[k].out_i();
		cout << "   ";
		cout << "a1[" << k << "].j=";
		a1[k].out_j();
		cout << endl;
	}
	return 0;
}

类中的内联函数
建立
用修饰符inline 说明成员函数
两种情况 或者是在类定义中成员函数前 或者卸载类定义外定义函数时的函数名前
1:
class sample
{
private:
int value;
public:
inline void put_value(int i);//定义内联函数在类定义内
int get_value(void);
};
2:
inline void sample::put_value(int i)//定义内联函数在类定义外
{
value =i;
}
隐式内联函数
在类定义内 直接定义成员函数时 成员函数就自动的转换为 内联函数 因此不需要修饰符inline 这样定义的成员函数就是隐式内联函数
例子

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class sample
{
public:
	sample();
	~sample();
	void put_value(int i) { value = i; }
	int get_value(void) { return value; }
private:
	int value;
};

sample::sample()
{
}

sample::~sample()
{
}
int main()
{
	sample a, b;
	a.put_value(10);
	b.put_value(100);
	cout << "value of object a is " << a.get_value() << "\n";
	cout << "value of object b is " << b.get_value() << "\n";
	return 0;
}

类的友元函数

虽然通过类将数据和代码封装起来 给程序带来很大好处 但是 由于绝对 不允许类外的函数访问类的私有数据 有时候 也会带来不便 这种限制给两个或多个类要共享同一函数或数据 带来困难 如 两个类 有关系 但是他们的 对象之间 不能对对方的私有数据进行访问 如 x类的对象a 不能访问类y的对象的b的私有成员
为了解决 引入有缘成员的概念 同过友元成员达到外部函数函数直接访问类的私有数据的目的 有缘成员把原来没有联系的类或函数联系起来 友元 成员用关键字 friend 声明 友元函数 可以声明在类的任何地方 私有部分和共有部分 一个函数可以是多个类的友元函数 但需要在各类中分别声明 而友元函数的定义既可以在类的内部 也可以在类的外部
友元函数访问类的成员时 需要在参数中给出所要访问的对象
友元成员有三种 友元函数 友元成员函数 友元类
定义友元函数
如果把一个独立的非成员函数说明为类的友元 则称该函数为友元函数
这个函数 能够访问该类的私有部分
这种友元函数虽然是在 类内声明或定义的 但它不是类的成员 它不属于任何类 他是普通函数 在类中声明友元函数的形式
friend 函数原型声明;
例子

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class A
{
public:
	A();
	~A();
	void set_a(int x)
	{
		a = x;
	}
	int get_a()
	{
		return a;
	}
	friend void square(A& y);
private:
	int a;
};
void square(A& m)
{
	cout << m.a * m.a << endl;
}
A::A()
{
}

A::~A()
{
}
int main()
{
	A obj_a;
	obj_a.set_a(10);
	square(obj_a);
	cout << obj_a.get_a();

	return 0;
}

友元函数的意义就是 它增加了类与外部的接口 因为它可以直接访问对象的 私有成员 节省了调用类成员函数的开销
定义友元成员函数
如果一个类的成员函数声明为另一个类的友元 则称这个成员函数为友元成员函数 这样就使两个类进行某种联系 相互配合工作 定义友元成员函数的一般形式
friend 返回值类型 类名 :: 函数名(参数);
例子:
两个类 x1 x2 在类x2中 成员函数 prin()被说名为类x1 的友元
friend void x1::prin(x2 a);
函数prin成为类x1 的友元函数
class x1
{
public:
void prin(x2 a);
}
这样 类x 1 的对象通过 友元成员函数 就能够访问类x2 的私有数据成员了
友元成员函数让两个类联系起来进行两个类的私有数据间的运算

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class x2;
class x1
{
public:
	x1();
	~x1();
	void set_value(int i, float f);
	void prin(x2 a);

private:
	int i;
	float f;

};

x1::x1()
{
}

x1::~x1()
{
}
class x2
{
public:
	x2();
	~x2();
	void set_value(int k,float p);
	friend void x1::prin(x2 a);
private:
	int k;
	float p;
};

x2::x2()
{
}

x2::~x2()
{
}
void x1::set_value(int x, float y)
{
	i = x;
	f = y;
	return;
}
void x2::set_value(int z,float w)
{
	k = z;
	p = w;
	return;
}
void x1::prin(x2 a)
{
	i = a.k * 2 + i;
	f = a.p * 2 + f;
	cout<<" i= "<<i<<"  f= "<<f<<endl;
	return;
}
int main(int argc,char *argv[],char *env[])
{
	x1 x1_a;
	x2 x2_a;
	x1_a.set_value(1, 1.5);
	x2_a.set_value(10, 10.5);
	x1_a.prin(x2_a);
	return 0;
}

定义友元类
一个类也可以声明为另一个类的友元类 其目的也是为了将两个类联系起来
定义友元类的一般形式
friend class 类名;
当一个类x1 声明为 另一个类x2 的友元类后 x2 类的 对象就可以访问类x1 的私有成员了

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class x2;
class x1
{
	friend class x2;//声明类x1 是x2的友元类 也就是类x2的对象能访问x1的私有数据,x1单方面认为x2是x1的好朋友 把隐私给x2看
public:
	x1();
	~x1();
	void set_value(int i, float f);
	void prin();

private:
	int i=0;
	float f=0;

};

x1::x1()
{
}

x1::~x1()
{
}
class x2
{
public:
	x2();
	~x2();
	void set_value(int k,float p);
     void prin(x1 s,x2 w);
private:
	int k=0;
	float p=0;
};

x2::x2()
{
}

x2::~x2()
{
}
void x1::set_value(int x, float y)
{
	i = x;
	f = y;
	return;
}
void x2::set_value(int z,float w)
{
	k = z;
	p = w;
	return;
}
void x2::prin(x1 s,x2 w)//类x2的成员函数访问类x1的私有成员函数 
{
	s.i = w.k * 2 + s.i;
	s.f = w.p * 2 + s.f;
	cout<<" s.i= "<<s.i<<"  s.f= "<<s.f<<endl;
	return;
}
void x1::prin()
{
	cout<<"i="<<i<<"  f=" <<f<<endl;
}
int main(int argc,char *argv[],char *env[])
{
	x1 x1_a;
	x2 x2_b;
	x1_a.set_value(1, 1.5);
	x2_b.set_value(10, 10.5);
	x1_a.prin();
	x2_b.prin(x1_a,x2_b);
	return 0;
}

最后指出 一 类之间的友元关系是不可传递的 你是我的朋友 他是你的朋友 他不一定是我的朋友 而是友元关系不可逆 这意味 a是b的友元 但b不一定 是a的友元
类的静态成员
在c++的类中 引入了静态数据成员和静态成员函数 的概念 静态成员 用static 说明 其一般形式为
static 数据成员 ;
static 成员函数 ;
当说明一个类的对象时 就为该对象产生的所有成员数据的拷贝 并为之分配内存 但当成员数据被说明为静态成员后 无论产生多少个类的对象 仅产生一个拷贝 并且第一个对象生成时 就将所有 静态数据初始化为 0 这个类的所有对象共享该静态成员
静态数据成员
不过一个类的对象有多少个 其静态数据成员却只有一个 由这些对象共享 而普通数据成员 是属于每个对象的 分配有各自的存储空间
例子

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class counter
{
private:
	static int count;//要初始化 在所有函数的外部进行初始化static成员需要单独定义
	//int count;
	char counter_ID;
public:
	counter();
	~counter();
	void inc_counter() { count++; }
	void set_counter_ID(char ch) { counter_ID = ch; }
	void show_counter()
	{
		cout << counter_ID << ":" << count << endl;
	}

};
//int counter::count = 100;//让静态数据成员的初始值为任意指定的数 这个初始值在类定义之外给定 
counter::counter()
{
}

counter::~counter()
{
}
int main()
{
	counter c1, c2;
	c1.set_counter_ID('A');
	c2.set_counter_ID('B');
	c1.show_counter();
	c2.show_counter();
	c1.inc_counter();
	c2.inc_counter();
	c1.show_counter();
	c2.show_counter();

	return 0;
}

静态成员函数
当一个成员函数定义为静态成员函数 他就不能访问非静态数据 也不能调用静态成员函数 静态成员函数只能访问所有 静态成员也就是说静态函数 只能访问其他静态函数或数据
因为静态成员函数不与类的对象相联系 所以 访问静态成员函数时 可以不需要对象( 也可以通过对象调用) 但需要在函数名前类名和作用域符 ::

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class counter
{
public:
	counter();
	~counter();
	void inc() { num++; }
	static int get() { return num; }
private:
	static int num;
};
int counter::num = 10;
counter::counter()
{
}

counter::~counter()
{
}
int main()
{
	counter a, b;
	cout<<counter::get()<<endl;
	a.inc();
	cout << counter::get() << endl;
	b.inc();
	cout << a.get() << endl;
	cout << counter::get() << endl;
	return 0;
}

对象作为函数的参数
同其他数据类型一样对象也可以多为函数的参数 在函数间传递 传递对象给函数 既可以是值传递 地址(指针)传递 也可以是引用传递 由于引用传递比指针传递更为简单 所以c ++中通常以引用传递代替指针传递
值传递
用值传递的方法将对象传递给函数 就是把对象的拷贝(不是对象本身 )传递个函数 因此 函数中对对象的任何修改 均不影响对象本身原来的值
例子 :

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class A;
void func_op(A y);//函数说明 参数为对象
class A
{
public:
	A();
	~A();
	void set_i(int x) { i = x; }
	void out_i() { cout << i << "\n"; }
private:
	int i;
};

A::A()
{
}

A::~A()
{
}
int main(void)
{
	A test;
	test.set_i(50);
	func_op(test);
	cout << "in mian i= ";
	test.out_i();//看看这个test 对象的成员i变化没有
	return 0;
}
void func_op(A y)
{
	y.set_i(100);
	cout << "in fun_op i= ";
	y.out_i();
	return;
}

引用传递
函数参数的引用传递方法 通过在函数说明的参数表中的参数名前加& 运算符 一次告诉编译器进行引用调用 引用调用的结果 将影响对象本身的值

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class A;
void swap(A& y, A& x);
class A
{
public:
	A();
	~A();
	void set_i(int x) { i = x; }
	void out_i() { cout << i << "\n"; }
private:
	int i;
};

A::A()
{
}

A::~A()
{
}
int main(void)
{
	A a1, a2;
	a1.set_i(50);
	a2.set_i(100);
	cout << " a1.i= ";
	a1.out_i();
	cout << "a2.i= ";
	a2.out_i();
	cout << endl;
	swap(a1, a2);
	cout << " a1.i= ";
	a1.out_i();
	cout << "a2.i= ";
	a2.out_i();
	cout << endl;
	return 0;
}
void swap(A& y, A& x)
{
	A temp;
	temp = y;
	y = x;
	x = temp;
	return;
}

类的指针
到目前为止 我们一直用直接引用的方法访问对象 在直接放喂牛想的情况下 是用 选择符. 来访问对象的成员的 指向类的指针的使用方法 对结构的指针相似 使用指向符 ->
对象指针

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class ptr_samp
{
public:
		ptr_samp();
	~ptr_samp();
	void set_num(int x) { num = x; }
	void out_num() { cout << num << endl; }
private:
	int num;
};

ptr_samp::ptr_samp()
{
}

ptr_samp::~ptr_samp()
{
}
int main()
{
	ptr_samp obj, * ptr;
	ptr = &obj;
	ptr->set_num(100);
	ptr->out_num();
	return 0;
}

和其他数据类型数组一样 对象数组也可以使用指针对于对象数组来说 指针的加一和减一 就自动地指向相邻的对象
例子

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class ptr_samp
{
public:
	ptr_samp();
	~ptr_samp();
	void set_data(int x, char y) { num = x; ch = y; }
	void out_data() { cout << num << "  " << ch << "\n"; }
private:
	int num;
	char ch;
};

ptr_samp::ptr_samp()
{
}

ptr_samp::~ptr_samp()
{
}
int main()
{
	ptr_samp obj[3], * ptr;
	ptr = &obj[0];
	char c = 'a';
	for (int i = 0; i < 3; i++)
	{
		ptr->set_data(10 * (i + 1),c);
		ptr->out_data();
		ptr++;
		c++;
	}
	return 0;
}

this指针
每一个类的成员函数都有一个隐藏的常量指针 称为 this 指针 this指针的类型就是成员函数所属类的类型 每当调用成员函数 时 他被初始化为 被调用函数 所在类的 对象的地址 也就是自动地将对象的指针传给它 用这个 this指针就可以访问相关的对象 因此 this指针 的作用时指向 调用成员函数的对象本身 通常不需要显式地使用this指针 当成员函数被调用时 这个指针自动的嫦娥了成员函数 他对所有成员函数来说都是隐含参数 但如果有必要 如需要返回一个指向当前对象的指针 也可以显式使用

void set_num(int x){num=x;}
给私有变量赋值 num=x ;
实际上就是
this->num=x;
两个例子结束 本章

#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class num
{
public:
	num();
	~num();
	void assign_value(int val) { this->x = val; }
	int  get_value() { return this->x; }
private:
	int x;
};

num::num()
{
}

num::~num()
{
}
int main()
{
	num a;
	a.assign_value(31);
	cout << "assigned (分配) value is : " <<a.get_value();

	return 0;
}
#include<stdio.h>
#include<iostream>//ctrl+d 选中所有相同的单词(代码)
using namespace std;
class POINT
{
public:
	POINT();
	~POINT();
	void change(int, int);
	void get_xy();
	void set_xy(int a,int b) { x = a; y = b; }
private:
	int x;
	int y;
};
POINT::POINT()
{
}

POINT::~POINT()
{
}
void POINT::get_xy()
{
	cout << "x and y: " << x << "," << y << endl;
}
void POINT::change(int a, int b)
{
	POINT new_loc;
	new_loc.set_xy(a, b);
	*this = new_loc;
}
int main()
{
	POINT loc;
	loc.set_xy(10, 10);
	cout << "loc ";
	loc.get_xy();
	loc.change(300,460);
	cout << "loc after change : ";
	loc.get_xy();
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值