本文深入探讨了C++编程语言中的高级语法,包括类和对象、虚函数与多态、模板以及异常处理等核心概念。此外,文章还介绍了C++标准模板库(STL)中的常用容器和算法。通过丰富的示例代码,读者可以更好地理解和掌握这些C++高级语法资料。
深入理解类和对象
类的定义与成员函数
在C++中,类是定义数据成员和成员函数的蓝图。数据成员是指类中的变量,成员函数则是类中的方法。类的定义通常包括成员变量和成员函数。下面是一个类定义的示例:
class Car {
public:
int speed;
string brand;
string model;
void start() {
cout << "Car is starting..." << endl;
}
void stop() {
cout << "Car is stopping..." << endl;
}
};
在这个示例中,Car
类有两个数据成员speed
、brand
、model
和两个成员函数start
和stop
。
对象的创建与使用
创建类的对象需要使用关键字new
,或者直接在栈上创建。对象的使用包括对成员变量的访问和成员函数的调用。
// 栈上创建对象
Car myCar;
myCar.speed = 60;
myCar.brand = "Toyota";
myCar.model = "Corolla";
myCar.start();
// 堆上创建对象
Car* myCarPtr = new Car;
myCarPtr->speed = 80;
myCarPtr->brand = "Honda";
myCarPtr->model = "Civic";
myCarPtr->start();
// 删除堆上的对象
delete myCarPtr;
构造函数与析构函数
构造函数在创建对象时被调用,用于初始化对象。析构函数在对象销毁时被调用,用于清理资源。构造函数可以有参数,也可以是默认的无参数版本。析构函数通常没有参数,并且名称前面有一个波浪号~
。
class Car {
public:
int speed;
string brand;
string model;
Car() {
speed = 0;
brand = "Unknown";
model = "Unknown";
}
Car(int s, string b, string m) {
speed = s;
brand = b;
model = m;
}
~Car() {
cout << "Car object is being destroyed." << endl;
}
void start() {
cout << "Car is starting..." << endl;
}
void stop() {
cout << "Car is stopping..." << endl;
}
};
int main() {
Car myCar;
myCar.start();
Car myCar2(100, "Toyota", "Corolla");
myCar2.start();
return 0;
}
静态成员变量与成员函数
静态成员变量和成员函数属于类,而不是单个对象。这意味着它们在整个类的生命周期内共享同一份数据。
class Car {
public:
static int carCount;
Car() {
carCount++;
}
~Car() {
carCount--;
}
static void printCarCount() {
cout << "Total cars: " << carCount << endl;
}
};
int Car::carCount = 0;
int main() {
Car myCar1;
Car myCar2;
Car::printCarCount();
return 0;
}
友元函数与友元类
友元函数或友元类可以访问类的私有成员。友元关系是单向的,类可以声明某个函数或类为友元,但友元函数或类并不反过来成为类的友元。
class Car {
private:
int speed;
public:
Car(int s) : speed(s) {}
friend void printSpeed(Car &car);
};
void printSpeed(Car &car) {
cout << "Car speed: " << car.speed << endl;
}
int main() {
Car myCar(60);
printSpeed(myCar);
return 0;
}
深拷贝与浅拷贝
浅拷贝的概念与实现
浅拷贝是指复制对象时,仅复制对象的指针或引用,而没有复制指针或引用所指向的数据。这意味着如果对象包含动态分配的内存,浅拷贝会导致数据被多个对象共享。
class Car {
public:
int* speed;
Car(int s) : speed(new int(s)) {}
~Car() {
delete speed;
}
Car(const Car& other) : speed(new int(*other.speed)) {}
Car& operator=(const Car& other) {
if (this != &other) {
delete speed;
speed = new int(*other.speed);
}
return *this;
}
};
int main() {
Car myCar(60);
Car myCarCopy = myCar;
*myCarCopy.speed = 80;
cout << "myCar speed: " << *myCar.speed << endl;
cout << "myCarCopy speed: " << *myCarCopy.speed << endl;
return 0;
}
深拷贝的概念与实现
深拷贝是指复制对象时,不仅复制对象的指针或引用,还复制指针或引用所指向的数据。这意味着每个对象都有自己的数据副本,不会共享数据。
class Car {
public:
int* speed;
Car(int s) : speed(new int(s)) {}
~Car() {
delete speed;
}
Car(const Car& other) : speed(new int(*other.speed)) {}
Car& operator=(const Car& other) {
if (this != &other) {
delete speed;
speed = new int(*other.speed);
}
return *this;
}
};
int main() {
Car myCar(60);
Car myCarCopy = myCar;
*myCarCopy.speed = 80;
cout << "myCar speed: " << *myCar.speed << endl;
cout << "myCarCopy speed: " << *myCarCopy.speed << endl;
return 0;
}
如何正确使用拷贝构造函数和赋值操作符
为了正确处理自定义对象的复制,需要正确实现拷贝构造函数和赋值操作符。拷贝构造函数用于创建新对象的副本,赋值操作符用于将一个对象的值赋给另一个对象。
class Car {
public:
int* speed;
Car(int s) : speed(new int(s)) {}
~Car() {
delete speed;
}
// 拷贝构造函数
Car(const Car& other) : speed(new int(*other.speed)) {}
// 赋值操作符
Car& operator=(const Car& other) {
if (this != &other) {
delete speed;
speed = new int(*other.speed);
}
return *this;
}
};
int main() {
Car myCar(60);
Car myCarCopy = myCar;
*myCarCopy.speed = 80;
cout << "myCar speed: " << *myCar.speed << endl;
cout << "myCarCopy speed: " << *myCarCopy.speed << endl;
return 0;
}
虚函数与多态
虚函数的定义与使用
虚函数允许基类指针或引用指向派生类对象时,调用派生类的函数而不是基类的函数。虚函数通过virtual
关键字定义。
class Animal {
public:
virtual void makeSound() {
cout << "Animal makes a sound." << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "Dog barks." << endl;
}
};
int main() {
Animal* animalPtr = new Dog();
animalPtr->makeSound();
delete animalPtr;
return 0;
}
多态的基本概念与实现
多态是指一个基类指针或引用可以指向不同的派生类对象,并根据对象的类型调用不同的成员函数。
class Animal {
public:
virtual void makeSound() {
cout << "Animal makes a sound." << endl;
}
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "Dog barks." << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
cout << "Cat meows." << endl;
}
};
int main() {
Animal* animalPtr = new Dog();
animalPtr->makeSound();
delete animalPtr;
animalPtr = new Cat();
animalPtr->makeSound();
delete animalPtr;
return 0;
}
抽象类与纯虚函数
抽象类是不能实例化的类,通常用于定义基类接口。纯虚函数是声明时没有实现的虚函数,用于强制派生类提供实现。
class Animal {
public:
virtual void makeSound() = 0; // 纯虚函数
};
class Dog : public Animal {
public:
void makeSound() override {
cout << "Dog barks." << endl;
}
};
class Cat : public Animal {
public:
void makeSound() override {
cout << "Cat meows." << endl;
}
};
int main() {
Animal* animalPtr = new Dog();
animalPtr->makeSound();
delete animalPtr;
animalPtr = new Cat();
animalPtr->makeSound();
delete animalPtr;
return 0;
}
C++模板
模板的基本概念与使用
模板允许在编译时生成特定类型的代码,提高了代码的泛型性。模板可以用于函数和类。
template <typename T>
T add(T a, T b) {
return a + b;
}
int main() {
cout << add<int>(5, 10) << endl;
cout << add<double>(5.5, 10.5) << endl;
return 0;
}
函数模板与类模板
函数模板可以接收任意类型的参数,而类模板则可以在类中使用模板参数。
template <typename T>
class MyClass {
public:
T value;
MyClass(T val) : value(val) {}
void printValue() {
cout << "Value: " << value << endl;
}
};
int main() {
MyClass<int> myInt(5);
myInt.printValue();
MyClass<double> myDouble(5.5);
myDouble.printValue();
return 0;
}
模板特化
模板特化允许为特定类型定义特殊的模板实现。例如,对于字符串类型,我们可以提供一个特化的实现。
template <typename T>
class MyClass {
public:
T value;
MyClass(T val) : value(val) {}
void printValue() {
cout << "Value: " << value << endl;
}
};
template <>
class MyClass<string> {
public:
string value;
MyClass(string val) : value(val) {}
void printValue() {
cout << "String Value: " << value << endl;
}
};
int main() {
MyClass<int> myInt(5);
myInt.printValue();
MyClass<string> myString("Hello");
myString.printValue();
return 0;
}
异常处理
异常处理的基本概念
C++中的异常处理机制允许程序在运行时检测并处理错误。通过try-catch
块捕获并处理异常。
try-catch语句的使用
try
块中的代码可能会抛出异常,catch
块用于捕获这些异常。
void divide(int a, int b) {
if (b == 0) {
throw "Division by zero error.";
}
cout << "Result: " << a / b << endl;
}
int main() {
try {
divide(10, 0);
} catch (const char* msg) {
cout << "Caught exception: " << msg << endl;
}
return 0;
}
抛出异常与捕获异常
可以使用throw
关键字抛出异常,使用catch
块捕获这些异常。
void divide(int a, int b) {
if (b == 0) {
throw runtime_error("Division by zero error.");
}
cout << "Result: " << a / b << endl;
}
int main() {
try {
divide(10, 0);
} catch (const runtime_error& ex) {
cout << "Caught exception: " << ex.what() << endl;
}
return 0;
}
自定义异常类
可以定义一个自定义异常类来捕获特定类型的异常。
class DivisionByZeroException : public exception {
public:
const char* what() const throw() {
return "Division by zero error.";
}
};
void divide(int a, int b) {
if (b == 0) {
throw DivisionByZeroException();
}
cout << "Result: " << a / b << endl;
}
int main() {
try {
divide(10, 0);
} catch (const DivisionByZeroException& ex) {
cout << "Caught exception: " << ex.what() << endl;
}
return 0;
}
常用STL容器与算法
STL容器的基本使用
C++ STL提供了多种容器,如vector
、list
、map
等,用于存储和操作数据。
#include <vector>
#include <list>
#include <map>
int main() {
// vector
vector<int> vec = {1, 2, 3, 4, 5};
for (int i : vec) {
cout << i << " ";
}
cout << endl;
// list
list<int> lst = {10, 20, 30, 40, 50};
for (int i : lst) {
cout << i << " ";
}
cout << endl;
// map
map<int, string> m = {{1, "One"}, {2, "Two"}, {3, "Three"}};
for (const auto& kv : m) {
cout << kv.first << ": " << kv.second << endl;
}
return 0;
}
常见STL算法介绍与使用
STL提供了一系列算法,如sort
、find
、for_each
等,用于处理容器中的数据。
#include <algorithm>
#include <vector>
int main() {
vector<int> vec = {5, 2, 9, 1, 5, 6};
sort(vec.begin(), vec.end());
for (int i : vec) {
cout << i << " ";
}
cout << endl;
auto it = find(vec.begin(), vec.end(), 5);
if (it != vec.end()) {
cout << "Found 5 at index " << distance(vec.begin(), it) << endl;
}
for_each(vec.begin(), vec.end(), [](int& v) {
cout << v << " ";
});
cout << endl;
return 0;
}
迭代器的基本操作
迭代器是一种可以遍历容器中元素的数据类型。迭代器提供了一种通用的方式来访问容器中的元素。
#include <vector>
#include <iostream>
int main() {
vector<int> vec = {10, 20, 30, 40, 50};
// 使用迭代器访问元素
vector<int>::iterator it = vec.begin();
while (it != vec.end()) {
cout << *it << " ";
it++;
}
cout << endl;
// 使用迭代器修改元素
it = vec.begin();
*it = 100;
cout << "Modified elements: ";
for (int i : vec) {
cout << i << " ";
}
cout << endl;
return 0;
}
通过以上内容,你可以深入理解C++中的类和对象、深拷贝与浅拷贝、虚函数与多态、模板、异常处理以及常用STL容器与算法,从而更好地掌握C++编程语言。
共同学习,写下你的评论
评论加载中...
作者其他优质文章