1. C++结构体和C结构体的区别
C++中的结构体在某些方面与类类似,而C中的结构体更像是一组相关的变量的集合。
具体来说包括以下六点:
- 访问权限;
- 成员函数;
- 构造函数和析构函数;
- 继承;
- 初始化;
- 名称空间.
1. 访问权限:
C++中的结构体支持三种访问权限,而C中的结构体内部成员变量只能是private
public
表示该成员可以被该类的任何对象、任何函数和其他类中的成员函数访问;private
表示该成员只能被该类的成员函数访问,其他函数和其他类都无法访问;protected
表示该成员可以被该类的成员函数和该类的派生类的成员函数访问,其他函数和其他类都无法访问。
2. 成员函数:
C++中的结构体可以包含成员函数,而C中的结构体只能包含成员变量。
3. 构造函数和析构函数:
C++中的结构体可以有构造函数和析构函数,而C中的结构体没有。
构造函数和析构函数:
- 构造函数
- 构造函数与类同名,
- 没有返回值,可以有参数,可以被重载。
- 每个对象在创建时都会自动调用构造函数,确保对象的成员变量被正确初始化。
- 如果没有定义构造函数,C++会自动生成一个默认构造函数,但该构造函数不会进行任何初始化操作。
- 析构函数:
- 析构函数与类同名,在名称前加上一个波浪号
~
。- 没有返回值,没有参数,不可被重载。
- 在对象被销毁时自动调用,释放对象占用的资源。
- 如果没有自定义析构函数,编译器会提供默认的析构函数。默认的析构函数不执行任何操纵。
4. 继承:
C++中的结构体可以继承自其他结构体或类,而C中的结构体不支持继承。
5. 成员初始化:
C++中的结构体可以使用成员初始化列表初始化其成员变量,而C中的结构体只能在定义后逐个成员变量进行初始化。
6. 名称空间:
C++中的结构体可以定义在名称空间中,而C中的结构体不能。
- 在 C++ 中,可以使用
namespace
关键字来定义一个名称空间。并且支持嵌套,即在一个名称空间中定义一个名称空间。- C中,没有名称空间的概念。
- 下面是定义名称空间的语法:
#include <iostream>
using namespace std;
// 定义名称空间 MySpace
namespace MySpace {
int my_variable = 10;
void my_function() {
cout << "Hello from MySpace!" << endl;
}
}
int main() {
// 访问名称空间 MySpace 中的变量和函数
cout << MySpace::my_variable << endl;
MySpace::my_function();
return 0;
}
- 嵌套名称空间
namespace OuterSpace {
int outer_variable = 10;
namespace InnerSpace {
int inner_variable = 20;
}
}
cout << OuterSpace::outer_variable << endl;
cout << OuterSpace::InnerSpace::inner_variable << endl;
举个结构体包含成员函数、析构函数和构造函数的例子,以及继承的使用。
#include <iostream>
struct MyStruct {
int x;
MyStruct(int a) : x(a) { // 构造函数
std::cout << "MyStruct constructed with " << a << std::endl;
}
~MyStruct() { // 析构函数
std::cout << "MyStruct destructed with " << x << std::endl;
}
void print() { // 成员函数
std::cout << "x = " << x << std::endl;
}
};
struct MyDerivedStruct : public MyStruct {
std::string name;
MyDerivedStruct(int a, const std::string& s) : MyStruct(a), name(s) { // 构造函数
std::cout << "MyDerivedStruct constructed with " << a << " and " << s << std::endl;
}
void setName(const std::string& s) { // 成员函数
name = s;
}
};
int main() {
MyDerivedStruct obj(42, "Alice");
obj.print();
obj.setName("Bob");
std::cout << "MyDerivedStruct's name is " << obj.name << std::endl;
return 0;//结构体obj被释放后会自动调用析构函数,所以最后打印MyStruct destructed with 42
}
MyStruct constructed with 42
MyDerivedStruct constructed with 42 and Alice
x = 42
MyDerivedStruct's name is Bob
MyStruct destructed with 42
最后顺便说说C++中,结构体和类的区别:
在C++中,结构体和类的区别是很小的,甚至可以说只有默认访问控制不同.
- 默认访问权限:对于类而言,成员默认的访问权限是
private
;而对于结构体而言,成员默认的访问权限是public
。- 继承:类支持
public
、protected
和private
三种继承方式,而结构体只支持public
继承方式。- 使用场景:类通常用于面向对象的程序设计,它更加注重数据和操作的封装和抽象,用于定义复杂的对象类型;而结构体通常用于简单的数据类型的定义和组织,主要用于存储数据。
2. 定义一个类,默认会生成哪些函数?
默认构造函数(Default constructor): 如果没有显式定义,编译器会自动生成一个默认构造函数,用于创建对象。
拷贝构造函数(Copy constructor):用于将一个已经存在的对象拷贝到新的对象中,如对象作为函数参数传递、返回对象时会被调用。
移动构造函数(Move constructor):C++11新增的功能,用于将一个右值对象(rvalue)的资源转移给另一个对象,减少资源拷贝的开销。
析构函数(Destructor):对象销毁时被调用,用于释放对象占用的资源,如内存、文件句柄等。
拷贝赋值函数(Copy assignment operator):用于将一个已经存在的对象赋值给另一个对象。
移动赋值函数(Move assignment operator):C++11新增的功能,用于将一个右值对象的资源转移给另一个对象。
等于运算符重载函数(Equality operator overload):用于比较两个对象是否相等。
输出流运算符重载函数(Output stream operator overload):用于将对象输出到输出流中,如std::cout。
输入流运算符重载函数(Input stream operator overload):用于从输入流中读取对象,如std::cin。
需要注意的是,如果定义了拷贝构造函数、拷贝赋值函数或析构函数,则需要同时定义移动构造函数和移动赋值函数,否则编译器会生成默认版本的移动函数,这些函数可能会导致程序性能下降。此外,如果定义了等于运算符重载函数,则建议同时定义不等于运算符重载函数。
#include <iostream>
#include <string>
class MyClass {
public:
// 默认构造函数
MyClass() : num_(0), str_("") {
std::cout << "Default constructor called" << std::endl;
}
// 拷贝构造函数
MyClass(const MyClass& other) : num_(other.num_), str_(other.str_) {
std::cout << "Copy constructor called" << std::endl;
}
// 拷贝赋值函数
MyClass& operator=(const MyClass& other) {
std::cout << "Copy assignment operator called" << std::endl;
if (this != &other) {
num_ = other.num_;
str_ = other.str_;
}
return *this;
}
// 移动构造函数
MyClass(MyClass&& other) noexcept : num_(std::move(other.num_)), str_(std::move(other.str_)) {
std::cout << "Move constructor called" << std::endl;
}
// 移动赋值函数
//&&是右值引用的声明符号,noexcept是指示符,表示该函数不会抛出异常。
MyClass& operator=(MyClass&& other) noexcept {
std::cout << "Move assignment operator called" << std::endl;
if (this != &other) {
num_ = std::move(other.num_);
str_ = std::move(other.str_);
}
return *this;
}
// 析构函数
~MyClass() {
std::cout << "Destructor called" << std::endl;
}
// ==运算符重载函数
bool operator==(const MyClass& other) const {
return num_ == other.num_ && str_ == other.str_;
}
// <<运算符重载函数
//输入运算符重载函数的第一个参数是标准输入流对象std::istream&,因此它无法访问类的私有成员。
//为了让输入运算符重载函数能够访问私有成员,需要将其声明为类的友元函数。声明为友元函数后,输入运算符重载函数就可以访问类的私有成员了。
friend std::ostream& operator<<(std::ostream& os, const MyClass& obj) {
os << "Num: " << obj.num_ << ", Str: " << obj.str_;
return os;
}
// >>输入运算符重载函数
friend std::istream& operator>>(std::istream& is, MyClass& obj) {
is >> obj.num_ >> obj.str_;
return is;
}
private:
int num_;
std::string str_;
};
int main() {
// Default constructor
MyClass obj1;
// Copy constructor
MyClass obj2(obj1);
// Copy assignment operator
MyClass obj3 = obj2;
// Move constructor
MyClass obj4(std::move(obj3));
// Move assignment operator
MyClass obj5;
obj5 = std::move(obj4);
// Operator overloading for ==
MyClass obj6(10, "hello");
MyClass obj7(10, "world");
if (obj6 == obj7) {
std::cout << "Equal" << std::endl;
}
else {
std::cout << "Not equal" << std::endl;
}
// Output stream operator overloading
MyClass obj8(5, "hi");
std::cout << obj8 << std::endl;
// Input stream operator overloading
MyClass obj9;
std::cin >> obj9;
std::cout << obj9 << std::endl;
return 0;
}
Default constructor called
Copy constructor called
Copy assignment operator called
Move constructor called
Move assignment operator called
Not equal
Num: 5, Str: hi
10 world
Num: 10, Str: world
Destructor called
Destructor called
Destructor called
Destructor called
Destructor called
3. 简述一下C++语言的特点有哪些?
1 .面向对象:C++是一种面向对象的编程语言,支持封装、继承和多态等面向对象特性。
2. 高效性:C++ 是一种编译型语言,能够直接转化为机器语言,因此具有高效性和高性能。同时,C++ 还支持底层操作,如指针和内存管理,可以直接访问计算机硬件资源。
3. 可移植性:C++程序可以在不同的操作系统和计算机平台上编译和运行。
4. 灵活性:C++提供了丰富的语法结构和数据类型,程序员可以根据需要自由地定义类、函数和变量等。
5. 扩展性:C++ 支持面向对象编程和模板编程,可以定义自己的类和数据类型,也可以编写自己的模板库,提高程序的可扩展性。
6. 可靠性:C++具有类型检查和内存安全等特性,可以有效地避免程序中的一些错误。增加了const参量、引用、四类cast转换、智能指针、try-catch等。
7. 可复用性高:C++的语法比较复杂,但是它提供了许多高级编程工具,例如类库和模板,可以提高程序员的开发效率。C++ 标准库提供了丰富的 API,包括容器、算法、字符串处理、正则表达式、数学计算、日期时间等等,使得程序开发更加高效。