Class
类的成员
通常,在头文件(h/hpp)中声明类和它的成员,在 cpp 文件中给出函数的实现。
类的成员默认为private类型,可用访问说明符控制可见性。访问说明符可以任意顺序,任意次数出现.
- private: 尽可被类的成员访问
- public: 在整个程序内可访问
C++也兼容 C 语言的
struct,struct默认成员类型为public,在 C++中,这是struct与class的唯一区别.
hello.h
#include <iostream>
#include <string>
class greeting {
std::string name; // private
public:
greeting(std::string); // Constructor
void sayHello();
};
hello.cpp
#include "hello.h"
greeting::greeting(std::string s) { name = s; }
void greeting::sayHello(){
std::cout<<"hello "<<name<<std::endl;
}
int main() {
greeting a("mirpri");
a.sayHello();
return 0;
}
构造函数
未手动定义构造函数时,编译器自动生成无参的构造函数。手动定义了构造函数后,不再自动生成默认的无参构造函数。
构造函数需要定义为public类型才能被调用。
class A{
int x,y;
};
class B{
int x,y;
public:
B(int a,int b):x{a}, y{b}{}
B()=default; //让编译器生成默认无参构造函数
};
int main(){
A a1;
B b1, b2(1,2);
return 0;
}
有时无法生成默认的构造函数,如含有:
- 引用类型的成员
- const 成员
- 不能无参初始化的类作为成员
class B{
public:
B(int x){}
};
class A{
int x,y;
//int &p;
//const int t;
//B b;
};
int main(){
cout<<"start";
A a1;
return 0;
}
委托构造 [C++11]
非委托构造函数直接初始化成员变量,委托构造函数调用其他构造函数完成初始化。
class A{
int x,y;
public:
A(int a, int b):x{a},y{b}{}
A(int a):A(a, a+1){} //委托构造
};
构造函数定义的隐式转换
默认情况下,构造函数能够在需要隐式转换时进行隐式转换。
使用explicit关键字可以阻止。
允许隐式转换为 Number:
#include<iostream>
using namespace std;
class Number {
int value;
public:
Number(int x) : value(x) {}
int getValue(){
return value;
}
};
void display(Number n) {
cout<<n.getValue()<<endl;
}
int main() {
display(5);
Number n=10;
display(n);
return 0;
}
不允许隐式转换:
#include<iostream>
using namespace std;
class Number {
int value;
public:
explicit Number(int x) : value(x) {}
int getValue(){
return value;
}
};
void display(Number n) {
cout<<n.getValue()<<endl;
}
int main() {
display(static_cast<Number>(5));
Number n(10);
display(n);
return 0;
}
析构函数
当未手动定义析构函数时, 系统生成默认的无参数析构函数.
析构函数可以被主动调用, 应防止重复释放资源操作.
友元 (friend)
类可以允许其他类或者函数访问它的非公有成员,方法是令其他类或者函数成为它的友元.
#include <iostream>
using namespace std;
class SecretKeeper {
int secret = 42; // private member
public:
// 声明友元函数
friend void peekSecret(const SecretKeeper& keeper);
};
// 友元函数定义
void peekSecret(const SecretKeeper& keeper) {
cout << "I know the secret: " << keeper.secret << endl;
}
int main() {
SecretKeeper keeper;
peekSecret(keeper);
// cout << keeper.secret << endl; // error
return 0;
}
继承
- 基类: 提供成员的类, 抽象/一般化
- 派生类: 接受成员的类, 具体
访问权限
Introducing
protected:
派生类能够访问, 而不允许其它用户访问
基类的私有(private)成员不能被派生类 (非基类友元)成员函数 访问.
具体而言, 继承后基类成员在派生类中的访问权限:
| 基类成员类型 | private 继承 | protected 继承 | public 继承 |
|---|---|---|---|
| protected | private | protected | protected |
| public | private | protected | public |
| private | NA | NA | NA |
继承的类型: - private: 默认 - protected - public
#include <iostream>
class A {
int x=1;
protected:
int m=2;
public:
int a=3;
};
class B : A { // 默认为private继承
public:
void print(){
//std::cout<<x<<std::endl; // error
std::cout<<m<<std::endl;
std::cout<<a<<std::endl;
}
};
class C : public A{};
int main() {
B b;
b.print();
//std::cout<<b.a; // error
C c;
std::cout<<c.a<<std::endl;
return 0;
}