C++类基础
#include <iostream>
using namespace std;
class Stack //类,面向对象,类名为Stack
{
public: //以下内容均为public,可供类外调用
Stack(); //类的构造器constructor,在每次声明类的对象时执行初始化操作
Stack(const int); //构造器的格式为 类名(参数可选) ,构造器没有返回值不写void,多个构造器构成重载,注意避免重载和默认参数二义性
~Stack(); //析构器destructor,在对象释放时执行,格式为 ~类名() ,无参无返回不写void
//构造器和析构器在没有手动定义的情况下会默认生成无参空函数
bool push(char); //在类中可以写完整的函数定义,如果分成头文件和.cpp两部分应在头文件中只写函数声明
bool isFull() //所有在类声明中定义的方法都将自动内联
{
return top >= size; //调用的top、size均为类的成员/字段,在类中可直接调用
}
bool isempty()
{
return top <= 0;
}
char pop(); //类的普通函数/成员函数需声明返回值类型
private: //以下内容均为private私有,在类外无法直接调用
char* arr; //成员arr,指针用于指向数组
int size=1024; //默认数组的大小,c++11类内初始化(之前版本不允许)
int top=0; //栈顶,默认没有项
}; //头文件截止
//.cpp文件
Stack::Stack() //Stack类的名称空间,不会和文件中全局函数Stack()冲突(如果有的话)
{
arr = new char[size]; //构造器中创建数组内存块
}
Stack::Stack(const int s) //接收一个参数,用于指定栈的大小
{
size = s>0?s:size; //防御性代码
arr = new char[size]; //类的函数中可以直接使用类的成员,即使在类声明外
//函数中没有打算改变s的值,所以声明为const,尽量使用const提高函数的兼容性/避免用变量接收调用时传入的常量
}
//错误: Stack::size = 20; 在类外只能访问类的public内容,在public的函数中可以访问private成员(就像上面的构造函数中访问size)
Stack::~Stack()
{
delete[]arr; //释放构造阶段分配的空间
}
bool Stack::push(char ch) //向栈中压入项
{
if (isFull())
return false;
arr[top++] = ch;
return true;
}
char Stack::pop()
{
if (isempty())
return NULL;
return arr[--top];
}
//如果在类外写作inline char Stack::pop() {}将函数定义为内联函数,类声明中的函数原型不需要写inline,所以将函数定义写在类声明中等价于在类外写inline定义
int mainclass1()
{
Stack sta; //创建对象,该对象大小为成员大小的总和(有可能因为对齐要求补一些空位),即char* arr 8/int size 4/int top 4总共16,不包含arr指向的动态内存,也不包含函数
cout << sizeof(sta) << endl;
sta.push('c');
cout<<sta.pop()<<endl;
Stack sta2(16); //调用有参构造器
char ch = 'a';
while (sta2.push(ch++))
{
continue;
}
while (!sta2.isempty())
{
cout << sta2.pop();
}
//sta和sta2均为自动变量,所在块结束时会释放,自动调用~Stack()析构器
Stack sta4(16), sta5(32), sta6; //前两个使用有参构造器,最后一个使用无参构造器
Stack* ps = new Stack; //ps是指针,占一个指针的大小8字节,指向new动态分配的内存空间,new Stack调用无参构造器,将对象(16字节)的地址传给ps
delete ps; //动态变量ps需要手动释放,调用delete释放ps指向的空间时会先执行对象的析构器
Stack* ps2 = new Stack(16); //调用有参构造器
delete ps2;
Stack sta3 = Stack(16); //等价于Stack sta3(16); 创建一个对象后标识为sta3,实际经过编译后标识符sta3不存在,直接使用sta3的地址
//如果类中没有声明成员,则类的大小为1(占位用),即便没有成员、没有手动声明构造器,创建对象时依然会执行默认生成的构造器,即创建对象一定会进行初始化,即便初始化操作没有改变任何东西/没有做任何事
//Stack c;只要创建对象,无论这语句写在哪里,都会执行初始化
return 0;
}
class Stack2
{
//不写访问控制默认private
int size_; //可以采用p_size或者size_表示数据成员
public:
Stack2(int size) //形参正常书写便于用户理解
{
size_ = size; //size_对应size便于维护,且用户无法看到私有的size_成员,只能看到构造器中形参名size
}
};
class claSt1
{
int i;
char c;
double d;
};
void mainclaSt1()
{
cout << sizeof(claSt1); //int占4字节char占1字节,但double对齐要求为8所以char之后空出3字节,实际大小16字节
}