C++:类


一、类

class Box
{
	public://底下的都声明为public访问限制
		double length;   // 盒子的长度
		double breadth;  // 盒子的宽度
		
		Box(void)//析构函数重载
		{
			length=10;
			breadth=10;
		}
			
		Box(int length)//使用this指针
		{
			this->length=length;
			breadth=10;
		}

		Box(int l,int b):length(l),breadth(b)//使用初始化列表来初始化字段
		{
			length=10;
		}
		
		~Box();// 析构函数声明

		double getVolume(void)//成员函数方式1:声明为内联函数
		{
			return length * breadth;
		}
		
		void Box::setLength(double len);//成员函数方式2:在类的外部使用范围解析运算符 :: 定义该函数
	
	private://底下的都声明为private访问限制,privatepublic等访问控制符谁上谁下无所谓
		int sell;
};

void Box::setLength(double len)
{
    length = len;
}

Box::()
{
	
}
int main()
{
	Box myBox;          // 创建一个对象
 	myBox.getVolume();  // 调用该对象的成员函数
}

类:

  • class是首字母小写

成员函数定义:

  • 定义成员函数方式1:内联函数形式
  • 定义成员函数方式2:在类的外部要使用范围解析运算符 :: 定义该函数

成员函数次序:
不像全局函数一样,顺序还是逆序都可以执行

#include<iostream>
using namespace std;

//顺序
class A
{
public:
	void hello()
	{
		cout<<"A:hello"<<endl;
	}

	void out()
	{
		hello();
	}
};

//逆序
class B
{
public:
	void out()
	{
		hello();
	}

	void hello()
	{
		cout<<"B:hello"<<endl;
	}
};

int main()
{
	A a;
	a.out();

	B b;
	b.out();
	/*
	A:hello
	B:hello
	*/
	return 0;
}

静态成员函数:
https://www.baidu.com/s?ie=UTF-8&wd=C++%E9%87%8D%E8%BD%BD%E6%93%8D%E4%BD%9C%E7%AC%A6

构造函数:

  • 同成员函数一样:有两种定义形式。
  • 可以定义多个析构函数重载,拥有不同参数列表。
  • 可以使用初始化列表来初始化字段

析构函数:

  • 必须是无参
    【理解:析构函数的意义】
    答:析构函数一般用来释放指针等,这样方便了项目开发。写完很长的代码后你很容易忘记释放指针,这样对系统是有害的。但当你把含有指针的操作封装成一个类,析构函数中写好释放指针。这样在程序结束时自动释放指针,超方便。

访问控制符:

  • 定义类内成员时:默认情况下,类的所有成员都是私有的。
  • 继承时:不显示声明是 private,protected,public 继承,则默认是 private 继承,在 struct结构体 中默认 public 继承:
    在这里插入图片描述
include <iostream>
using namespace std;
class Line {
	int a;
};
int main() {
	Line line;
	line.a = 5;//error
	cout << line.a << endl;
	//error
/*
这也算是访问控制符
*/
}
#include<iostream>
using namespace std;

class B
{
	int a = 10;//默认情况下,类的所有成员都是私有的。
public:
	int b = 100;
};

class D:public B{};

int main()
{
	D d;
	cout<<d.b<<endl;
	cout<<d.a<<endl;//error
	return 0;
}
#include<iostream>
#include<assert.h>
using namespace std;
 
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //正确
    cout << a1 << endl;   //正确
    cout << a2 << endl;   //正确
    cout << a3 << endl;   //正确
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : public A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //正确,public成员
    cout << a1 << endl;       //正确,基类的public成员,在派生类中仍是public成员。
    cout << a2 << endl;       //正确,基类的protected成员,在派生类中仍是protected可以被派生类访问。
    cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};
int main(){
  B b(10);
  cout << b.a << endl;
  cout << b.a1 << endl;   //正确
  cout << b.a2 << endl;   //错误,类外不能访问protected成员
  cout << b.a3 << endl;   //错误,类外不能访问private成员
  system("pause");
  return 0;
}
#include<iostream>
#include<assert.h>
using namespace std;
class A{
public:
  int a;
  A(){
    a1 = 1;
    a2 = 2;
    a3 = 3;
    a = 4;
  }
  void fun(){
    cout << a << endl;    //正确
    cout << a1 << endl;   //正确
    cout << a2 << endl;   //正确
    cout << a3 << endl;   //正确
  }
public:
  int a1;
protected:
  int a2;
private:
  int a3;
};
class B : private A{
public:
  int a;
  B(int i){
    A();
    a = i;
  }
  void fun(){
    cout << a << endl;       //正确,public成员。
    cout << a1 << endl;       //正确,基类public成员,在派生类中变成了private,可以被派生类访问。
    cout << a2 << endl;       //正确,基类的protected成员,在派生类中变成了private,可以被派生类访问。
    cout << a3 << endl;       //错误,基类的private成员不能被派生类访问。
  }
};
int main(){
  B b(10);
  cout << b.a << endl;       //正确。public成员
  cout << b.a1 << endl;      //错误,private成员不能在类外访问。
  cout << b.a2 << endl;      //错误, private成员不能在类外访问。
  cout << b.a3 << endl;      //错误,private成员不能在类外访问。
  system("pause");
  return 0;
}

构造析构顺序:

  • main()前顺序构造,main()后逆序析构
  • main()下面的也可以运行,被认为是全局变量(但int p=10;写在下面再在mian()中调用就会报错)
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class A
{
private:
	int k;
public:
	A(int num):k(num)
	{
		cout << "构造:" << k << endl;
	}
	~A()
	{
		cout<<"析构:"<<k<< endl;
	}
};

A a(100);
A b(200);
int main()
{
	static A x(500);
	A y(600);
	return 0;
}
A c(300);//main()下面的也是全局变量

/*
构造:100
构造:200
构造:300
构造:500
构造:600
析构:600
析构:500
析构:300
析构:200
析构:100
*/

二、继承

格式:

class SmallBox : public Box
{

}

三、多态

多态是继承的发展,构成多态的条件:

  • 必须存在继承关系;
  • 继承关系中必须有同名的虚函数,并且它们是覆盖关系(函数原型相同)。
  • 存在基类的指针,通过该指针调用虚函数。

例题

针对第二段是否是虚函数

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class B
{
public:
	void f()
	{
		cout << "f():B" << endl;
	}
	virtual void k()
	{
		cout << "k():B" << endl;
	}
};

class D:public B
{
public:
	void f()
	{
		cout << "f():D" << endl;
	}
	virtual void k()
	{
		cout << "k():D" << endl;
	}
};

int main()
{
	B* p = new D;
	p->f();//f():B
	p->k();//k():D
	/*
	f()不是虚函数,所以没有实现多态
	k()是虚函数,所以是多态
	*/
	return 0;
}

针对第二点的虚函数是否都实现

#include <iostream>
using namespace std;

//基类Base
class Base{
public:
    virtual void func();
    virtual void func(int);
};
void Base::func(){
    cout<<"void Base::func()"<<endl;
}
void Base::func(int n){
    cout<<"void Base::func(int)"<<endl;
}

//派生类Derived
class Derived: public Base{
public:
    void func();
    void func(char *);
};
void Derived::func(){
    cout<<"void Derived::func()"<<endl;
}
void Derived::func(char *str){
    cout<<"void Derived::func(char *)"<<endl;
}

int main(){
    Base *p = new Derived();
    p -> func();  //输出void Derived::func().调用的是派生类的虚函数,构成了多态。
    p -> func(10);  //输出void Base::func(int).不是多态
    p -> func("http://c.biancheng.net");  //compile error
    
/*
语句p -> func();派生类和基类都对它进行了实现

语句p -> func(10);调用的是基类的虚函数,因为派生类中没有函数覆盖它。

语句p -> func("http://c.biancheng.net");出现编译错误,因为通过基类的指针只能访问从基类继承过去的成员,不能访问派生类新增的成员。
*/

    return 0;
}

针对第三点:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>

using namespace std;

class A
{
public:
	virtual f()
	{
		cout << "A" << endl;
	}
};

class B :public A
{
public:
	void f(int x)
	{
		cout << x << endl;
	}
};

int main()
{
	B myB;
	myB.f();//error
/*
这不是多态,不存在指针,更不存在指向基类的指针。所以这只是调用一个类里的成员函数,显而易见,B类没有定义成员函数f()。
*/
	return 0;
}

虚函数

  • 解决问题:通过基类指针只能访问派生类的成员变量,但是不能访问派生类的成员函数的问题
  • 纯虚函数:
    • 纯虚函数是在声明虚函数时被“初始化”为0的函数。
    • 声明格式:virtual 函数类型 函数名 (参数表列) =0;
      注意:
      ①纯虚函数没有函数体;
      ②最后面的“=0”并不表示函数返回值为0,它只起形式上的作用,告诉编译系统“这是纯虚函数”;
      ③这是一个声明语句,最后应有分号。
      ④纯虚函数只有函数的名字而不具备函数的功能,不能被调用。它只是通知编译系统: “在这里声明一个虚函数,留待派生类中定义”。在派生类中对此函数提供定义后,它才能具备函数的功能,可被调用。

模板

自定义栈类

#include <iostream>
using namespace std;
const int Max_SIZE=100;//定义栈大小

class Stack
{
public:
    Stack();
    ~Stack();
    void Push(int x);//入栈
    void Pop();//出栈
    int GetTop();//取栈顶元素
    bool IsEmpty();//判空
    bool IsFull();//判满
    int GetSize();//取栈中元素个数
private:
    int *data;
    int top;//栈顶标记位
};

Stack::Stack()
{
    top=0;
    data=new int [Max_SIZE];
}

Stack::~Stack()
{
    delete [] data;
}

bool Stack::IsFull()
{
    if(top>=Max_SIZE) return true;
    else return false;
}

bool Stack::IsEmpty()
{
    if(top==0) return true;
    else return false;
}

void Stack::Push(int x)
{
    if(!IsFull())
    {
        data[top++]=x;
    }
    else
    {
        cout<<"Stack is Full!"<<endl;
    }
}

void Stack::Pop()
{
    if(!IsEmpty())
    {
        top--;//移动栈顶即可
    }
    else
    {
        cout<<"Stack is Empty!"<<endl;
    }
}

int Stack::GetTop()
{
    return data[top-1];
}

int Stack::GetSize()
{
    return top;
}

int main()
{
    Stack s;
    int a,n;
    cout<<"元素入栈(用空格分隔),输入-1结束:";
    while(!s.IsFull())
    {
        cin>>n;
        if(n==-1) break;
        else s.Push(n);
    }
    cout<<"栈中元素个数:";
    cout<<s.GetSize()<<endl;
    cout<<"栈中元素出栈:";
    while(!s.IsEmpty())
    {
        a=s.GetTop();
        s.Pop();
        cout<<a<<" ";
    }
    cout<<endl<<endl;
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值