03.面向对象程序设计

本文详细介绍了C++中的类定义、成员访问控制、构造函数(包括默认构造、复制构造和移动构造)、析构函数、虚函数、内联函数、静态成员、继承(单一和多重)、嵌套类以及匿名类的概念和使用。
摘要由CSDN通过智能技术生成

类定义

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()
{
}

匿名类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值