#c++类设计:
1,类的访问权限:成员和类的默认访问修饰符是私有的(private)
public 共有的;
(访问跟struct一样)
private 私有的;
是不可访问的,可以通过类和友元函数访问。
protected 受保护的;
保护成员和私有成员相似(可以通过类和友元函数访问),但是保护成员在派生类(即子类)可以访问。
类内存:
它与结构体一样的内存结构(内存对齐)
1,静态变量不占用类内存。virtual 关键字定义的函数也占内存
2,引用如果在类中定义,它是一个指针占4个字节
内联函数:inline
作用:提高函数的执行效率。
用法:用关键字inline函数定义的前面,里面的代码一般不超过10行
内联函数不要包含循环,虚函数,递归, 区分宏定义
友元函数:friend
友元可以是函数,可以是类;友元函数可以直接访问类的私有成员。
注意:它是定义在类外的普通函数,它不属于任何类。(声明函数里面没有this指针)
缺点:破坏了类的封装性和数据的隐藏性,导致程序可维护性变差。
隐含的this指针:
在c++中,每一个对象都能通过this指针来访问自己的地址。this指针是所有的成员函数的隐含参数。因此在函数内部,它可以用来指向调用对象。
struct和class的区别:
默认访问权限:class是private,struct是public
默认继承权限:class是private,struct是public
class可用于定义模板参数,像typename,而struct不行
#include <iostream>
//私有的访问:
using namespace std;
class person{
private:
//friend int age; //加了友元函数就变成共有的了可以被访问
//int main(); //友元函数
//class my; //友元类
int age; //这个是this->age//变量 变量名一样加this区分
public:
void setAge(int age)
{
this->age = age;
}
int getAge()
{
return this->age;
}
};
int main ()
{
person A; //实例化
A.setAge(20);
cout << A.getAge() << endl;
return 0;
}
#include <iostream>
//受保护的访问:
using namespace std;
class Person{
protected:
int m_age;
};
class Student:public Person{ // Student是person的子类(child)
public:
void setAge(int age)
{
m_age = age;
}
int getAge()
{
return m_age;
}
};
int main ()
{
Student A;
A.setAge(20);
cout << A.getAge() << endl;
return 0;
}
成员变量(相当于属性) 成员函数(方法)
static 静态成员变量:
特点:在类的所有对象中共享。
在static中,不能用this指针
必须在类外进行初始化。
类中的静态函数中只能访问类中的静态成员。
静态变量不占用类内存。virtual 关键字定义的函数也占内存
#include <iostream>
using namespace std;
class person{
public:
static int counts;
person()//类的构造函数
{
counts++;
}
};
int person::counts = 1; //类外进行初始化。
int main ()
{
person A;
cout << person::counts << endl;
return 0;
}
const:
特点:const在定义时必须初始化。const int a = 10;(a的值改变不了)
在类中cosnt成员初始化只能在列表中,不能进行赋值。
const修饰的函数内不能有赋值操作,const修饰的变量不允许被修改。
#include <iostream>
using namespace std;
class person{
private:
int m_age;
string m_name;
public:
void setAge(int age);
int getAge() const;
const string &getname()const;
void setname(const string &n);
};
int main ()
{
return 0;
}
其他变量成员:
成员变量是指针,在构造,赋值等操作时一般会动态分配一段内存空间用于存数据,而不是直接将别人的地址存到指针。并且在释放对象时在析构函数需要先将动态内存释放掉。
成员变量为数组时:类的成员变量不能使用成员初始化表进行初始化,而只是通过在构造函数体中对数组的各个成员进行赋值。
构造函数一般用于初始化,析构函数一般用于释放内存(创建 new delete)
构造函数:是类的一种特殊的成员函数,在每次创建类的新对象时执行。
析构函数:是类的一种特殊的成员函数,在每次删除类的新对象时执行。
构造函数:默认创建调用 析构函数:默认释放调用。
注:1,创建构造和析构函数之后不会默认创建;
2,都没有返回值,和类名一样;
3,构造函数有参数,析构函数没有参数。
#include <iostream>
using namespace std;
class person{
private:
int m_age;
public:
person(); //构造函数声明格式
person(int age); //构造函数声明格式(重载的)
~person(); //析构函数声明格式
};
初始化列表:
与其他函数不同,构造函数除了有名字,参数列表和函数体之外,还可以有初始化列表,初始化列表以冒号开头,后跟一系列以逗号分隔的初始化字段。
初始化列表的必要性:
1,常量成员,因为常量只能初始化不能赋值,所以必须放在初始化列表里面
2,const和引用 需要初始化,可以放在初始化列表里,进行初始化。
3,没有默认构造函数的类类型。
#include <iostream>
using namespace std;
class MY{
private:
MY(int a);
};
class person{
private:
int m_age;
public:
person():m_age(10), con(10), n(m_age), b(100){} //初始化列表
const int con;
int &n;
MY b;
~person();
};
int main ()
{
MY b; //有参数不写,如果没有初始化运行不了
}
拷贝构造函数:
浅拷贝:如果按浅拷贝进行复制,复制完成后,两个对象涉及动态分配空间的变量,空间中的内容完全一样当对这两个对象析构时,会发生同一片空间被释放两次因而出现错误。
浅拷贝只是对指针进行复制,两个指针都指向同一个内存空间。
#include <iostream>
#include <string.h>
using namespace std;
// 浅拷贝构造
class Person{
private:
int m_age;
public:
//构造函数
Person(int age )
{
m_age = age;
}
//拷贝构造函数
Person(const Person &o)
{
this->m_age = o.m_age;
}
void show()
{
cout << m_age << endl;
}
};
int main()
{
Person A(10); //调用构造函数
Person B = A; //调用拷贝构造函数
Person C(A); //调用拷贝构造函数
A.show();
B.show();
C.show();
return 0;
}
深拷贝:不只是对指针进行复制,也对指针指向的内容进行复制,复制后,两个指针指向不同的内存空间。
#include <iostream>
#include <string.h>
using namespace std;
// 深拷贝构造
class Person{
public:
//构造函数
Person( int age , char *str = NULL ) : m_age ( age ) {
if( str == NULL ){
m_name = new char[1];
*m_name = '\0';
//m_name[0] = '\0';
}else{
m_name = new char[strlen( str ) + 1 ];
strcpy( m_name, str );
}
}
~Person( ){ //构造多态分配内存,析构是必须释放内存
delete []m_name;
}
//深拷贝构造函数
Person( const Person &o ){
this->m_age = o.age;
this->m_name = new char[ strlen( o.name ) + 1 ];
strcpy( this->m_name, o.m_name );
}
void show( ) const{
cout << "m_name = " << m_name << ", m_age = " << m_age << endl;
}
private:
int m_age;
char *m_name;
};
int main()
{
Person A(10, "abc"); //调用构造函数
Person B = A; //调用深拷贝构造函数
A.show(); //10 abc
B.show(); //10 abc
return 0;
}