C++ review
Class & Object
Class member function
Class member functions are those functions whose definition and prototype are written inside the class definition, just like other variables in the class definition. A class member function is a member of a class. It can manipulate any object of the class and can access all members of the object.
Code
class Box
{
public:
double length;
double breadth;
double height;
void move();
double getVolume()
{
return length * breadth * height;
}
};
class SmallBox:Box
{
public:
void setLength(double len);
double getLength();
SmallBox(double len); //构造函数
SmallBox(const SmallBox &obj); //拷贝构造函数
~SmallBox(); //析构函数
private:
double length1;
double *ptr;
};
Constructor
Execute when the object is created
//构造函数
SmallBox::SmallBox(double len): length1(len) //初始化列表
{
//length1 = len; //初始化列表写法等价于这个
cout<<"SmallBox对象被创建了"<<endl;
cout<<"初始化的len:"<<len<<endl;
ptr = new double;
*ptr = len;
}
Destructor
The destructor will be executed every time the created object is deleted
//析构函数会在每次删除所创建的对象时执行
SmallBox::~SmallBox()
{
cout<<"析构函数执行了,length:"<<*ptr<<endl;
cout<<"释放内存"<<endl;
delete ptr;
}
Copy function
Popular understanding is to assign a class to another class
//如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数
SmallBox::SmallBox(const SmallBox &obj)
{
cout<<"调用拷贝函数并且为指针ptr分配内存"<<endl;
//为指针分配内存
ptr = new double;
*ptr = *obj.ptr;
}
use:
SmallBox sbox1(7.7);
//此时会调用拷贝函数
SmallBox box2 = sbox1;
SmallBox box3 = sbox1;
Friend function
A friend can be a function, which is called a friend function; a friend can also be a class, which is called a friend class and is modified with the friend keyword
Declare friend functions:
class Box
{
double width;
public:
double length;
friend void printWidth( Box box );
void setWidth( double wid );
};
Define friend function:
// 请注意:printWidth() 不是任何类的成员函数
void printWidth( Box box )
{
/* 因为 printWidth() 是 Box 的友元,它可以直接访问该类的任何成员 */
cout << "Width of box : " << box.width <<endl;
}
Declare a friend class:
friend class ClassTwo;
Inline function
If a function is an inline function, the compiler will place a copy of the function in every place where the function is called. When the function is modified, it must be recompiled, otherwise the old code will be used and the inline function will be defined , The keyword inline needs to be placed before the function name , and the function needs to be defined before calling the function. If the defined function is more than one line, the compiler will ignore the inline qualifier
The functions defined in the class definition are all inline functions, even if the inline specifier is not used .
this pointer
Each object can use the this pointer to point to itself. The pointer is an implicit parameter of all member functions. Inside the member function, it can be used to point to the calling object
The friend function does not have this pointer, because the friend is not a member of the class. Only member functions have this pointer.
Sample code:
#include <iostream>
using namespace std;
class Box
{
public:
// 构造函数定义
Box(double l=2.0, double b=2.0, double h=2.0)
{
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
}
double Volume()
{
return length * breadth * height;
}
int compare(Box box)
{
return this->Volume() > box.Volume();
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
int main(void)
{
Box Box1(3.3, 1.2, 1.5); // Declare box1
Box Box2(8.5, 6.0, 2.0); // Declare box2
if(Box1.compare(Box2))
{
cout << "Box2 is smaller than Box1" <<endl;
}
else
{
cout << "Box2 is equal to or larger than Box1" <<endl;
}
return 0;
}
operation result:
Constructor called.
Constructor called.
Box2 is equal to or larger than Box1
Pointer to class
Sample code:
#include <iostream>
using namespace std;
class Box
{
public:
// 构造函数定义
Box(double l=2.0, double b=2.0, double h=2.0)
{
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
}
double Volume()
{
return length * breadth * height;
}
private:
double length; // Length of a box
double breadth; // Breadth of a box
double height; // Height of a box
};
int main(void)
{
Box Box1(3.3, 1.2, 1.5); // Declare box1
Box Box2(8.5, 6.0, 2.0); // Declare box2
Box *ptrBox; // Declare pointer to a class.
// 保存第一个对象的地址
ptrBox = &Box1;
// 现在尝试使用成员访问运算符来访问成员
cout << "Volume of Box1: " << ptrBox->Volume() << endl;
// 保存第二个对象的地址
ptrBox = &Box2;
// 现在尝试使用成员访问运算符来访问成员
cout << "Volume of Box2: " << ptrBox->Volume() << endl;
return 0;
}
Results of the
Constructor called.
Constructor called.
Volume of Box1: 5.94
Volume of Box2: 102
Static members of the class
We can use the static keyword to define class members as static. When we do this, it means that no matter how many objects we commonly use, there is always only one static member in memory, or in other words, all objects share the same static member.
We can't put the initialization of static members in the definition of the class. You can re-declare the static variable outside the class by :: to initialize it
Static member variables:
Sample code:
#include <iostream>
using namespace std;
class Box
{
public:
static int objectCount;
Box()
{
// 每次创建对象时增加 1
objectCount++;
}
};
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
int main(void)
{
Box Box1(); // 声明 box1
Box Box2(); // 声明 box2
// 输出对象的总数
cout << "Total objects: " << Box::objectCount << endl;
return 0;
}
Results of the:
Total objects: 2
Static member function:
- +Static functions can be accessed as long as they use the class name and scope resolution operator ::
- Static member functions can only access static member data, other static member functions and other functions outside the class
- Static member functions have a class scope, and they cannot access the this pointer of the class. You can use static member functions to determine whether certain objects of the class have been created.
The difference between static member function and ordinary member function:
- Static member functions have no this pointer and can only access static members (including static member variables and static member functions).
- Ordinary member functions have this pointer and can access any member in the class; while static member functions do not have this pointer.
Sample code:
#include <iostream>
using namespace std;
class Box
{
public:
static int objectCount;
// 构造函数定义
Box(double l=2.0, double b=2.0, double h=2.0)
{
cout <<"Constructor called." << endl;
length = l;
breadth = b;
height = h;
// 每次创建对象时增加 1
objectCount++;
}
double Volume()
{
return length * breadth * height;
}
static int getCount()
{
return objectCount;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 初始化类 Box 的静态成员
int Box::objectCount = 0;
int main(void)
{
// 在创建对象之前输出对象的总数
cout << "Inital Stage Count: " << Box::getCount() << endl;
Box Box1(3.3, 1.2, 1.5); // 声明 box1
Box Box2(8.5, 6.0, 2.0); // 声明 box2
// 在创建对象之后输出对象的总数
cout << "Final Stage Count: " << Box::getCount() << endl;
return 0;
}
Results of the:
Inital Stage Count: 0
Constructor called.
Constructor called.
Final Stage Count: 2
inherit
- concept
When creating a class, you do not need to rewrite new data members and member functions, just specify that the newly created class inherits the members of an existing class. This existing class is called the base class , and the newly created class is called the derived class .
Suppose there is a base class Shape , and Rectangle is its derived class
// 基类
class Shape
{...}
// 派生类
class Rectangle: public Shape
{...}
-
Access control and inheritance
The derived class can access all the non-private members of the base class. Therefore, if members of the base class do not want to be accessed by member functions of the derived class, they should be declared as private in the base class.
A derived class inherits all base class methods, except in the following cases:
- The constructor, destructor, and copy constructor of the base class.
- The overloaded operator of the base class.
- Friend function of the base class.
-
Inheritance type
We hardly use protected or private inheritance, usually public inheritance. When using different types of inheritance, follow the following rules:
- Public inheritance (public): When a class is derived from the public base class, the base class's public member of the derived class public members of the base class to protect a member of the derived class to protect members of the base class's private members can not be directly derived class Access, but it can be accessed by calling the public and protected members of the base class .
- Protected inheritance (protected): When a class is derived from protecting base class, the base class public and protection of the members of the derived class will be to protect members.
- Private inheritance (private): When a class is derived from the private base class, the base class public and protection of the members of the derived class will become private members.
-
Multiple inheritance
In layman's terms, a sub-category has multiple parent categories and the characteristics of multiple parent categories
Syntax format:
Use commas to separate parent classes
class <派生类名>:<继承方式1><基类名1>,<继承方式2><基类名2>,… { <派生类类体> };
Example:
// 基类 Shape class Shape {...} // 基类 PaintCost class PaintCost {...} // 派生类 class Rectangle: public Shape, public PaintCost{...}
Overloaded operators and overloaded functions
Functions with the same name but different formal parameters (different number, type or order of parameters) constitute an overload
Example:
#include <iostream>
using namespace std;
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
int main(void)
{
printData pd;
// 输出整数
pd.print(5);
// 输出浮点数
pd.print(500.263);
// 输出字符串
char c[] = "Hello C++";
pd.print(c);
return 0;
}
Results of the:
整数为: 5
浮点数为: 500.263
字符串为: Hello C++
An overloaded operator is a function with a special name . The function name is composed of the keyword operator and the operator symbols to be overloaded later. Like other functions, overloaded operators have a return type and a parameter list. In layman's terms, redefine the function of the operator
Box operator+(const Box&);
Declare that the addition operator is used to add two Box objects. Therefore, when using it, you need to pass in two Box objects
Box operator+(const Box&, const Box&);
Example:
#include <iostream>
using namespace std;
class Box
{
public:
double getVolume(void)
{
return length * breadth * height;
}
void setLength( double len )
{
length = len;
}
void setBreadth( double bre )
{
breadth = bre;
}
void setHeight( double hei )
{
height = hei;
}
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}
private:
double length; // 长度
double breadth; // 宽度
double height; // 高度
};
// 程序的主函数
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 把体积存储在该变量中
// Box1 详述
Box1.setLength(6.0);
Box1.setBreadth(7.0);
Box1.setHeight(5.0);
// Box2 详述
Box2.setLength(12.0);
Box2.setBreadth(13.0);
Box2.setHeight(10.0);
// Box1 的体积
volume = Box1.getVolume();
cout << "Volume of Box1 : " << volume <<endl;
// Box2 的体积
volume = Box2.getVolume();
cout << "Volume of Box2 : " << volume <<endl;
// 把两个对象相加,得到 Box3
Box3 = Box1 + Box2;
// Box3 的体积
volume = Box3.getVolume();
cout << "Volume of Box3 : " << volume <<endl;
return 0;
}
The following is a list of operators that can be overloaded:
The following is a list of operators that cannot be overloaded:
- .: Member access operator
- . , -> : Member pointer access operator
- ::: Domain operator
- sizeof: length operator
- ?:: Conditional operator
- #: preprocessing symbol
Polymorphism
As the name implies, it means multiple forms, such as animals. The following subcategories include cats, dogs and sheep, etc..., cats, dogs and sheep are multiple forms of animals
C++ polymorphism means that when a member function is called, different functions will be executed according to the type of the object calling the function .
Sample code:
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// 程序的主函数
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();
// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();
return 0;
}
It will produce the following results:
Parent class area
Parent class area
Details, the above output result is wrong, the cause of the error is that the calling function area() is set as the version in the base class by the compiler. This is the so-called static polymorphism , or static linking -function calls are prepared before the program is executed All right. Also known as early binding , we only need to add the virtual keyword before the area() method in the Shape class ;
The modified output:
Rectangle class area
Triangle class area
At this point, the compiler looks at the content of the pointer, not its type
Each subclass has an independent implementation of the function area(). This is how polymorphism is generally used. With polymorphism, you can have multiple different classes, all with the same name but with different implementation functions, and the parameters of the function can even be the same.
-
Virtual function
A virtual function is a function declared in the base class using the keyword virtual . When redefining a virtual function defined in a base class in a derived class, it will tell the compiler not to link to the function statically.
-
Pure virtual function
You may want to define a virtual function in the base class so that you can redefine the function in the derived class to better apply to the object, but you cannot give a meaningful implementation of the virtual function in the base class. Pure virtual functions are used.
Virtual functions must not be defined. Pure virtual functions are used to standardize the behavior of derived classes, namely interfaces . A class containing pure virtual functions is an abstract class. An abstract class cannot define an instance, but it can declare a pointer or reference to a concrete class that implements the abstract class.
We can rewrite the virtual function area() in the base class as follows:
class Shape { protected: int width, height; public: Shape( int a=0, int b=0) { width = a; height = b; } // pure virtual function virtual int area() = 0; };
= 0 tells the compiler that the function has no body and the virtual function above is a pure virtual function .
Interface (abstract class)
-
concept
If at least one function in the class is declared as a pure virtual function, then this class is an abstract class. Pure virtual functions are specified by using "= 0" in the declaration, as shown below
class Box { public: // 纯虚函数 virtual double getVolume() = 0; private: double length; // 长度 double breadth; // 宽度 double height; // 高度 };
Subclasses of abstract classes must rewrite all pure virtual functions
-
Examples of abstract classes:
#include <iostream> using namespace std; // 基类 class Shape { public: // 提供接口框架的纯虚函数 virtual int getArea() = 0; void setWidth(int w) { width = w; } void setHeight(int h) { height = h; } protected: int width; int height; }; // 派生类 class Rectangle: public Shape { public: int getArea() { return (width * height); } }; class Triangle: public Shape { public: int getArea() { return (width * height)/2; } }; int main(void) { Rectangle Rect; Triangle Tri; Rect.setWidth(5); Rect.setHeight(7); // 输出对象的面积 cout << "Total Rectangle area: " << Rect.getArea() << endl; Tri.setWidth(5); Tri.setHeight(7); // 输出对象的面积 cout << "Total Triangle area: " << Tri.getArea() << endl; return 0; }
It will produce the following result:
Total Rectangle area: 35 Total Triangle area: 17
template
Templates are blueprints or formulas for creating generic classes or functions
Grammatical form:
template <typename type> ret-type func-name(parameter list)
{
// 函数的主体
}
type is the placeholder name of the data type used by the function . This name can be used in the function definition
Example:
#include <iostream>
#include <string>
using namespace std;
template <typename T>
inline T const& Max (T const& a, T const& b)
{
return a < b ? b:a;
}
int main ()
{
int i = 39;
int j = 20;
cout << "Max(i, j): " << Max(i, j) << endl;
double f1 = 13.5;
double f2 = 20.7;
cout << "Max(f1, f2): " << Max(f1, f2) << endl;
string s1 = "Hello";
string s2 = "World";
cout << "Max(s1, s2): " << Max(s1, s2) << endl;
return 0;
}
Syntax format:
template <class type> class class-name {
.
.
.
}
type is the placeholder type name, which can be specified when the class is instantiated. You can use a comma-separated list to define multiple generic data types.
Example:
#include <iostream>
#include <vector>
#include <cstdlib>
#include <string>
#include <stdexcept>
using namespace std;
template <class T>
class Stack {
private:
vector<T> elems; // 元素
public:
void push(T const&); // 入栈
void pop(); // 出栈
T top() const; // 返回栈顶元素
bool empty() const{ // 如果为空则返回真。
return elems.empty();
}
};
template <class T>
void Stack<T>::push (T const& elem)
{
// 追加传入元素的副本
elems.push_back(elem);
}
template <class T>
void Stack<T>::pop ()
{
if (elems.empty()) {
throw out_of_range("Stack<>::pop(): empty stack");
}
// 删除最后一个元素
elems.pop_back();
}
template <class T>
T Stack<T>::top () const
{
if (elems.empty()) {
throw out_of_range("Stack<>::top(): empty stack");
}
// 返回最后一个元素的副本
return elems.back();
}
int main()
{
try {
Stack<int> intStack; // int 类型的栈
Stack<string> stringStack; // string 类型的栈
// 操作 int 类型的栈
intStack.push(7);
cout << intStack.top() <<endl;
// 操作 string 类型的栈
stringStack.push("hello");
cout << stringStack.top() << std::endl;
stringStack.pop();
stringStack.pop();
}
catch (exception const& ex) {
cerr << "Exception: " << ex.what() <<endl;
return -1;
}
}
Results of the:
7
hello
Exception: Stack<>::pop(): empty stack