C++高频知识点(九)
文章目录
41. 如何区分一段代码是C++还是C代码编写的
区分一段代码是用C++还是C编写的,可以通过以下几个方面来判断:
1. 文件扩展名
- C代码:通常使用.c作为文件扩展名。
- C++代码:通常使用.cpp、.cc、.cxx、.C等作为文件扩展名。
2. 语言特性和语法
变量声明和定义
- C:变量必须在块的开头声明
C99 标准及后续版本
从 C99 标准(1999 年发布)开始,C 语言变得更加灵活,允许变量在 块的任何位置 声明。也就是说,变量可以在它们第一次使用之前声明,而不必放在函数体的开头。这个变化使得代码更加灵活和易于理解。
#include <stdio.h>
int main() {
int a = 10;
a = a + 1; // 可执行语句
int b = 20; // 非法:变量声明在可执行语句之后
return 0;
}


C++:支持类和对象,包含继承、多态等特性。
class Point {
public:
int x;
int y;
Point(int x, int y) : x(x), y(y) {}
void display() {
std::cout << x << ", " << y << std::endl;
}
};







42. 说一下C++的返回值优化

考虑以下的简单示例,演示了返回值优化的作用:
#include <iostream>
// 定义一个简单的类
class MyClass {
public:
// 默认构造函数
MyClass() { std::cout << "Default Constructor\n"; }
// 拷贝构造函数
MyClass(const MyClass& other) { std::cout << "Copy Constructor\n"; }
// 移动构造函数
MyClass(MyClass&& other) noexcept { std::cout << "Move Constructor\n"; }
};
// 返回一个对象的函数
MyClass createObject() {
return MyClass();
}
int main() {
MyClass obj = createObject();
return 0;
}
在上述示例中,createObject() 函数返回一个 MyClass 对象。根据返回值优化的原理,编译器可能会直接将这个对象构造在 main() 函数中的 obj 变量所在的空间中,而不需要额外的拷贝构造函数调用。如果编译器执行了返回值优化,输出将会是:
而不会输出额外的 “Copy Constructor”。这是因为编译器可以优化,避免了将临时对象复制给 obj 的过程,而是直接在 obj 的位置构造了该对象。

43. C++中为什么用类模板

5. 标准库支持:C++标准库中大量使用了模板类,例如容器类(如vector、list)、算法(如sort、find)等,这些模板类为C++程序员提供了强大且高效的工具。
示例:(如果不用模板 需要分别指定类型)
// 示例:模板类实现一个通用的堆栈数据结构
template <typename T>
class Stack {
private:
std::vector<T> elements;
public:
void push(const T& element) {
elements.push_back(element);
}
T pop() {
if (elements.empty()) {
throw std::out_of_range("Stack<>::pop(): empty stack");
}
T element = elements.back();
elements.pop_back();
return element;
}
bool empty() const {
return elements.empty();
}
};
int main() {
Stack<int> intStack;
intStack.push(10);
intStack.push(20);
intStack.push(30);
while (!intStack.empty()) {
std::cout << intStack.pop() << " ";
}
std::cout << std::endl;
Stack<std::string> stringStack;
stringStack.push("Hello");
stringStack.push("World");
while (!stringStack.empty()) {
std::cout << stringStack.pop() << " ";
}
std::cout << std::endl;
return 0;
}
在上述示例中,Stack 是一个模板类,可以用于存储不同类型的元素,如整数和字符串,同时保持相同的堆栈操作接口。这种灵活性和通用性使得模板类在现代C++编程中非常重要和常用。
44. 子类不能继承父类的函数有哪些
在C++中,子类(派生类)无法继承父类(基类)的以下内容:
2. 构造函数和析构函数:虽然构造函数和析构函数实际上是可以继承的,但它们不会被子类继承并且不会直接调用。子类需要自己定义构造函数和析构函数来初始化和清理自己的成员。
class Base {
public:
Base() {}
~Base() {}
};
class Derived : public Base {
// Derived 有一个默认构造函数和析构函数,
// 但它们不会继承 Base 的构造函数和析构函数
};
3. 父类中被子类重载的函数:如果子类重新定义了父类的同名函数(重载),则父类中该函数的其他版本对子类是不可见的。
class Base {
public:
void someFunction() {}
};
class Derived : public Base {
public:
void someFunction(int value) {}
// Derived 中的 someFunction 重载了 Base 中的 someFunction,
// Base 中的 void someFunction() 对 Derived 不可见
};
4. 静态成员函数和静态成员变量:子类可以继承父类的静态成员(也就是说可用,但不算继承),但不能直接继承父类的静态成员函数或静态成员变量。子类可以通过父类名字限定符来访问父类的静态成员,但这并不算继承。
class Base {
public:
static void staticFunction() {}
static int staticVariable;
};
int Base::staticVariable = 0;
class Derived : public Base {
};
// Derived 无法直接调用或继承 Base 的 staticFunction 和 staticVariable
5. 友元函数:如果父类声明了一个友元函数,子类并不会继承该友元函数的访问权限,除非子类也被声明为友元类。
class Base {
friend void friendFunction();
};
void friendFunction() {
Base b;
// 可以访问 Base 的私有成员,但 Derived 无法继承 friendFunction 的友元权限
}
class Derived : public Base {
// Derived 无法访问 friendFunction,也不会继承其友元权限
};
6. 虚函数的具体化:如果在父类中使用了 final 关键字,表示虚函数不可被子类重写。这意味着子类不能继承并重写这些具体化的虚函数。
class Base {
public:
virtual void finalFunction() final {}
};
class Derived : public Base {
// Derived 无法继承并重写 Base 中被 final 修饰的 finalFunction
};
45. 谈谈stl标准库的线程安全性


#include <mutex>
#include <vector>
std::vector<int> vec;
std::mutex mtx;
// 线程安全地向 vec 中添加元素
void addToVector(int value) {
std::lock_guard<std::mutex> lock(mtx);
vec.push_back(value);
}


之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!
更多推荐


所有评论(0)