下面是一个简单的C++面向对象编程示例,展示类、对象和基本成员的使用:
#include
#include
#include
using namespace std;
// 定义一个简单的类
class Person {
private:
string name; // 私有成员变量
int age;
public:
// 构造函数
Person(string n, int a) {
name = n;
age = a;
}
// 成员函数
void introduce() {
cout << "Hello, my name is " << name
<< " and I am " << age << " years old." << endl;
}
};
int main() {
SetConsoleOutputCP(CP_UTF8); // 设置控制台为 UTF-8 编码
// 创建对象
Person person1("Alice", 25);
// 调用成员函数
person1.introduce();
return 0;
}
这个程序展示了C++面向对象的基本特性:
class Person
):包含私有数据成员和公有成员函数运行输出:
Hello, my name is Alice and I am 25 years old.
下面是一个展示C++中友元(friend)功能的简单示例。友元允许特定的函数或类访问另一个类的私有成员:
#include
#include
using namespace std;
class Person {
private:
string name;
int age;
public:
// 构造函数
Person(string n, int a) {
name = n;
age = a;
}
// 声明友元函数
friend void showInfo(Person p);
};
// 友元函数定义,可以访问Person的私有成员
void showInfo(Person p) {
cout << "Name: " << p.name << ", Age: " << p.age << endl;
}
int main() {
// 创建对象
Person person1("Bob", 30);
// 调用友元函数
showInfo(person1);
return 0;
}
Person
类中通过 friend void showInfo(Person p);
声明 showInfo
为友元函数。name
和 age
是私有的,showInfo
函数仍能直接访问它们,因为它是友元。Name: Bob, Age: 30
如果你想要看友元类的用法,这里是一个扩展示例:
#include
#include
using namespace std;
class Person {
private:
string name;
int age;
public:
Person(string n, int a) : name(n), age(a) {}
// 声明另一个类为友元
friend class InfoPrinter;
};
// 友元类
class InfoPrinter {
public:
void display(Person p) {
cout << "Name: " << p.name << ", Age: " << p.age << endl;
}
};
int main() {
Person person1("Alice", 25);
InfoPrinter printer;
printer.display(person1);
return 0;
}
在这个例子中,InfoPrinter
类是 Person
的友元类,因此它可以访问 Person
的私有成员。输出与之前相同,但展示了类级别的友元关系。
当一个独立的函数需要访问类的私有数据,且不适合作为类的成员函数时,可以使用友元函数。
#include
#include
using namespace std;
class Box {
private:
double width;
double height;
public:
Box(double w, double h) : width(w), height(h) {}
// 声明友元函数
friend void printArea(Box b);
};
// 友元函数直接访问私有成员
void printArea(Box b) {
double area = b.width * b.height;
cout << "Area: " << area << endl;
}
int main() {
Box box(5.0, 3.0);
printArea(box);
return 0;
}
使用情况:printArea
不属于 Box
类,但需要计算和访问其私有成员。将其声明为友元避免了添加额外的公有 getter 函数。
当两个类相互依赖,并且一个类需要访问另一个类的私有成员时,可以将其中一个类声明为另一个类的友元。
#include
#include
using namespace std;
class Employee {
private:
string name;
double salary;
public:
Employee(string n, double s) : name(n), salary(s) {}
// 声明 Manager 为友元类
friend class Manager;
};
class Manager {
public:
void adjustSalary(Employee& e, double newSalary) {
e.salary = newSalary; // 直接访问私有成员
cout << e.name << "'s new salary: " << e.salary << endl;
}
};
int main() {
Employee emp("John", 50000);
Manager mgr;
mgr.adjustSalary(emp, 60000);
return 0;
}
使用情况:Manager
需要直接修改 Employee
的私有成员 salary
,通过友元关系实现紧密协作。
在重载操作符(如 +
, <<
)时,如果操作符函数不是类的成员函数,通常需要访问类的私有数据,这时可以声明为友元。
#include
#include
using namespace std;
class Point {
private:
int x;
int y;
public:
Point(int xVal, int yVal) : x(xVal), y(yVal) {}
// 声明友元函数重载 <<
friend ostream& operator<<(ostream& os, const Point& p);
};
// 友元函数实现
ostream& operator<<(ostream& os, const Point& p) {
os << "(" << p.x << ", " << p.y << ")";
return os;
}
int main() {
Point p(3, 4);
cout << p << endl;
return 0;
}
使用情况:<<
操作符需要访问 Point
的私有成员 x
和 y
,通过友元实现简洁的输出。
在开发过程中,为了测试类的私有成员状态,可以临时使用友元函数或友元类。
#include
using namespace std;
class System {
private:
int status;
public:
System(int s) : status(s) {}
// 声明友元函数用于调试
friend void debugStatus(System sys);
};
void debugStatus(System sys) {
cout << "System status: " << sys.status << endl;
}
int main() {
System sys(42);
debugStatus(sys);
return 0;
}
使用情况:debugStatus
用于检查 System
的内部状态,便于调试。
友元的使用情况主要集中在:
<<
, +
)下面是一个展示C++继承(Inheritance)基本概念的简单示例,包括基类、派生类和访问控制:
父类继承下来,会继承三样东西:
1.成员变量
2.成员函数
3.类型定义
#include
#include
using namespace std;
// 基类
class Animal {
protected: // protected成员可被派生类访问
string name;
int age;
public:
Animal(string n, int a) : name(n), age(a) {}
void eat() {
cout << name << " is eating." << endl;
}
};
// 派生类(公有继承)
class Dog : public Animal {
private:
string breed;
public:
// 构造函数,调用基类构造函数
Dog(string n, int a, string b) : Animal(n, a), breed(b) {}
void bark() {
cout << name << " (a " << breed << ") is barking!" << endl;
}
// 重写基类方法
void eat() {
cout << name << " (a " << breed << ") is eating dog food." << endl;
}
};
int main() {
// 创建基类对象
Animal animal("Generic", 5);
animal.eat();
// 创建派生类对象
Dog dog("Max", 3, "Golden Retriever");
dog.eat(); // 调用重写后的方法
dog.bark(); // 调用派生类特有方法
return 0;
}
Generic is eating.
Max (a Golden Retriever) is eating dog food.
Max (a Golden Retriever) is barking!
name
, age
)和行为(eat()
)。protected
访问修饰符,使派生类可以访问这些成员。public
继承方式从 Animal
继承。name
和 age
,并添加了自己的属性 breed
。Animal(n, a)
。Dog
类重写了基类的 eat()
方法,提供了更具体的实现。eat()
方法被覆盖,但仍可通过作用域解析运算符(如 Animal::eat()
)调用。你提到的 using type = int;
是C++11引入的类型别名(Type Alias)语法,用于为现有类型定义一个新的名称。它类似于 typedef
,但更灵活且可读性更好。下面我将解释它的用法,并结合虚函数和多态的上下文提供一个相关示例。
#include
using namespace std;
// 类型别名
using type = int; // "type" 现在是 "int" 的别名
int main() {
type number = 42; // 等价于 int number = 42;
cout << "Number: " << number << endl;
return 0;
}
Number: 42
using type = int;
定义 type
为 int
的别名。typedef int type;
等价,但 using
语法更直观,且支持模板。假设我们在一个多态场景中使用类型别名来简化代码:
#include
#include
#include
using namespace std;
// 类型别名
using Distance = double; // 为 double 定义别名
// 基类
class Vehicle {
protected:
string name;
public:
Vehicle(string n) : name(n) {}
// 虚函数
virtual Distance calculateFuelEfficiency() const {
return 0.0; // 默认实现
}
virtual ~Vehicle() {}
};
// 派生类1
class Car : public Vehicle {
private:
Distance miles;
Distance gallons;
public:
Car(string n, Distance m, Distance g) : Vehicle(n), miles(m), gallons(g) {}
Distance calculateFuelEfficiency() const override {
return miles / gallons; // 计算每加仑英里数
}
};
// 派生类2
class Bike : public Vehicle {
private:
Distance miles;
Distance liters;
public:
Bike(string n, Distance m, Distance l) : Vehicle(n), miles(m), liters(l) {}
Distance calculateFuelEfficiency() const override {
return miles / liters; // 计算每升英里数
}
};
int main() {
vector<Vehicle*> vehicles;
vehicles.push_back(new Car("Toyota", 300.0, 10.0));
vehicles.push_back(new Bike("Harley", 120.0, 2.0));
for (const auto* v : vehicles) {
Distance efficiency = v->calculateFuelEfficiency();
cout << "Fuel efficiency: " << efficiency << " miles per unit" << endl;
}
for (auto* v : vehicles) {
delete v;
}
return 0;
}
Fuel efficiency: 30 miles per unit
Fuel efficiency: 60 miles per unit
类型别名(using Distance = double;
):
double
定义为 Distance
,提高了代码的可读性,表示这是一个距离或效率相关的类型。Distance
,如果将来需要更改类型(如改为 float
),只需改别名定义。虚函数(calculateFuelEfficiency
):
Distance
。Car
和 Bike
重写该函数,计算不同的燃料效率。运行时多态:
Vehicle*
指针调用 calculateFuelEfficiency()
,运行时根据对象类型执行对应的实现。using
vs typedef
typedef
(C++98):typedef double Distance; // 传统方式
using
(C++11):using Distance = double; // 现代方式
using
支持模板别名,而 typedef
不支持:template<typename T>
using Ptr = T*; // 模板别名
Ptr<int> p = nullptr; // int* p
using
语法更直观,类似于赋值。Distance
表示距离相关的变量,而不是直接用 double
。using
在模板中更灵活,如定义容器别名:template<typename T>
using Vec = std::vector<T>;
Vec<int> v; // 等价于 std::vector