类
类定义
class dog
{
public:
dog()
{
_legs = 4;
_bark = true;
}
void setDogSize(string dogSize)
{
_dogSize = dogSize;
}
virtual void setEars(string type) // virtual function
{
_earType = type;
}
private:
string _dogSize, _earType;
int _legs;
bool _bark;
};
类型声明
dog mongrel;
类成员
成员访问控制
访问类型 | 含义 |
---|---|
private | 声明为 private 的类成员只能由类的成员函数和友元(类或函数)使用。 |
protected | 声明为 protected 的类成员可由类的成员函数和友元(类或函数)使用。 此外,它们还可由派生自该类的类使用。 |
public | 声明为 public 的类成员可由任意函数使用。 |
备注:访问控制同样适用于所有名称:成员函数、成员数据、嵌套类和枚举数。
private
class BaseClass {
public:
// privMem accessible from member function
int pubFunc() { return privMem; }
private:
int privMem;
};
class DerivedClass : public BaseClass {
public:
void usePrivate(int i)
{
//privMem = i;//error C2248: “BaseClass::privMem”: 无法访问 private 成员(在“BaseClass”类中声明)
}
};
class DerivedClass2 : private BaseClass {
public:
// pubFunc() accessible from derived class
int usePublic() { return pubFunc(); }
};
int main() {
BaseClass aBase;
DerivedClass aDerived;
DerivedClass2 aDerived2;
// aBase.privMem = 1; // error C2182: “privMem”: 非法使用“void”类型
// aDerived.privMem = 1; // error C2248: “BaseClass::privMem”: 无法访问 private 成员(在“BaseClass”类中声明)
// aDerived2.pubFunc(); // error C2247: “BaseClass::pubFunc”不可访问,因为“DerivedClass2”使用“private”从“BaseClass”继承
}
结论:
1)派生类公有成员函数无法访问基类的私有成员函数
2)类类型的对象无法访问私有成员(成员数据、成员函数)
protected
TODO
public
成员数据
可变成员数据
// mutable.cpp
class X
{
public:
bool GetFlag() const
{
m_accessCount++;
return m_flag;
}
private:
bool m_flag;
mutable int m_accessCount;
};
int main()
{
}
成员函数
#include <iostream>
using namespace std;
class Account
{
public:
// Declare the member function Deposit within the declaration
// of class Account.
double Deposit(double HowMuch)
{
balance += HowMuch;
return balance;
}
private:
double balance=0;
};
int main()
{
Account acc;
std::cout << "acc.Deposit(10.0)="<< acc.Deposit(10.0) << std::endl;
}
虚函数
#include <iostream>
using namespace std;
class Account {
public:
Account(double d) { _balance = d; }
virtual ~Account() {}
virtual double GetBalance() { return _balance; }
virtual void PrintBalance() { cerr << "Error. Balance not available for base type." << endl; }
private:
double _balance;
};
class CheckingAccount : public Account {
public:
CheckingAccount(double d) : Account(d) {}
void PrintBalance() { cout << "Checking account balance: " << GetBalance() << endl; }
};
class SavingsAccount : public Account {
public:
SavingsAccount(double d) : Account(d) {}
void PrintBalance() { cout << "Savings account balance: " << GetBalance(); }
};
int main() {
// Create objects of type CheckingAccount and SavingsAccount.
CheckingAccount checking(100.00);
SavingsAccount savings(1000.00);
// Call PrintBalance using a pointer to Account.
Account* pAccount = &checking;
pAccount->PrintBalance();
// Call PrintBalance using a pointer to Account.
pAccount = &savings;
pAccount->PrintBalance();
}
总结:
1)虚函数是可以在派生类中重新定义的成员函数,但它不是必需的。
2)如果声明的类不提供虚函数的重写实现,则使用基类虚函数实现。
3)虚函数的重写始终是虚拟的。
内联函数
#include <iostream>
using namespace std;
class Account
{
public:
// Declare the member function Deposit within the declaration
// of class Account.
double Deposit(double HowMuch)
{
balance += HowMuch;
return balance;
}
// Declare the member function Deposit but do not define it.
double Deposit1(double HowMuch);
private:
double balance = 0;
};
inline double Account::Deposit1(double HowMuch)
{
balance += HowMuch;
return balance;
}
int main()
{
Account acc;
std::cout << "acc.Deposit(10.0)=" << acc.Deposit(10.0) << std::endl;
std::cout << "acc.Deposit1(12.0)=" << acc.Deposit1(12.0) << std::endl;
}
总结:
1)通过关键字inline可以将类成员函数定义在类声明的外部
2)必须通过范围解析运算符 (:😃 用类名称限定定义中的函数名称
构造函数
默认构造函数
#include <iostream>
using namespace std;
class Box {
public:
//Box() { /*perform any required default initialization steps*/}// All params have default values
//Box(int w = 1, int l = 1, int h = 1) : m_width(w), m_height(h), m_length(l) {}
//Box(int width, int length, int height): m_width(width), m_length(length), m_height(height) {}
int Volume() { return m_width * m_height * m_length; }
private:
int m_width{ 0 };
int m_height{ 0 };
int m_length{ 0 };
};
int main() {
Box box1; // Invoke compiler-generated constructor
cout << "box1.Volume: " << box1.Volume() << endl; // Outputs 0
}
总结:
1)默认构造函数通常没有参数,但它们可以具有带默认值的参数。
2)如果类中未声明构造函数,则编译器提供隐式 inline 默认构造函数。
3)如果声明了任何非默认构造函数,编译器不会提供默认构造函数
复制构造函数
复制构造函数通过从相同类型的对象复制成员值来初始化对象。
移动构造函数
移动构造函数是特殊成员函数,它将现有对象数据的所有权移交给新变量,而不复制原始数据。
析构函数
析构函数是一个成员函数,在对象超出范围或通过调用 delete 或 delete[] 显式销毁对象时,会自动调用析构函数。 析构函数与类同名,前面带有波形符 (~)
静态成员
#include <iostream>
class BufferedOutput
{
public:
// Return number of bytes written by any object of this class.
short BytesWritten()
{
return bytecount;
}
// Reset the counter.
static void ResetCount()
{
bytecount = 0;
}
// Static member declaration.
static long bytecount;
};
// Define bytecount in file scope.
long BufferedOutput::bytecount;
int main()
{
BufferedOutput Console;
std::cout << "Console.bytecount="<< Console.bytecount << std::endl;
Console.bytecount = 100;
std::cout << "Console.bytecount=" << Console.bytecount << std::endl;
}
/*output:
Console.bytecount=0
Console.bytecount=100
*/
总结:
1)类的所有对象保留一个静态成员数据副本
2)静态成员数据必须在类声明的外部定义
3)可以在不引用类类型的对象的情况下访问静态成员数据
继承
单一继承
// deriv_SingleInheritance2.cpp
// compile with: /EHsc /c
#include <iostream>
using namespace std;
class Document {
public:
char* Name; // Document name.
void PrintNameOf(); // Print name.
};
// Implementation of PrintNameOf function from class Document.
void Document::PrintNameOf() {
cout << Name << endl;
}
class Book : public Document {
public:
Book(char* name, long pagecount);
private:
long PageCount;
};
// Constructor from class Book.
Book::Book(char* name, long pagecount) {
Name = new char[strlen(name) + 1];
strcpy_s(Name, strlen(Name), name);
PageCount = pagecount;
};
int main() {
// Create a new object of type Book. This invokes the
// constructor Book::Book.
string str = "Programming Windows, 2nd Ed";
auto c_string = &str[0];
Book LibraryBook(c_string, 944);
// Use PrintNameOf function inherited from class Document.
LibraryBook.PrintNameOf();
}
结论:
1)继承关系中,被继承的类被视为基类,继承的类视为派生类。
2)在继承中,派生类包含基类的非私有成员以及您添加的所有新成员。
3)范围解析运算符::引用派生类成员
多重继承
// deriv_MultipleBaseClasses.cpp
// compile with: /LD
class Collection {
};
class Book {};
class CollectionOfBook : public Book, public Collection {
// New members
};
__super
struct B1 {
void mf(int) {}
};
struct B2 {
void mf(short) {}
void mf(char) {}
};
struct D : B1, B2 {
void mf(short) {
__super::mf(1); // Calls B1::mf(int)
__super::mf('s'); // Calls B2::mf(char)
}
};
嵌套类
可以在一个类的范围内声明另一个类。 这种类称为“嵌套类”。
// nested_class_declarations.cpp
class BufferedIO
{
public:
enum IOError { None, Access, General };
// Declare nested class BufferedInput.
class BufferedInput
{
public:
int read();
int good()
{
return _inputerror == None;
}
private:
IOError _inputerror;
};
// Declare nested class BufferedOutput.
class BufferedOutput
{
// Member list
};
};
int main()
{
}