命名空间
不要在头文件内使用using namespace,一定要确保实在一个足够小的作用域下使用,在哪个范围内,比如函数、if语句等,但一定不要在头文件中使用!!!
上述示例中,会调用orange中的print,因为apple中的print输入需要做隐性转换,但如果把orange去掉,apple中又可以正常使用,这样很容易造成一些错误,所以一定不要轻易使用命名空间,就使用apple::print就可以。
C语言中没有命名空间的概念,所以函数名称都包括库名称,C++中则不必这样
引入命名空间的时候可以只引入其中某个函数,下图中endl就会报错,因为没有被引入其中:
using std::cout;
cout << "x" << endl;
命名空间可以嵌套:
namespace orange {
namespace apple {
void print() {
std::cout << "hello" << std::endl;
}
}
}
int main() {
using namespace orange;
using namespace apple;
print();
命名空间不能滥用,如果滥用了,那函数在命名空间中本来的含义又有什么意义呢
命名空间存在的意义就是在自己定义的命名空间里函数可以任意命名!
多线程
引入库文件
#include<thread>
任务:使用一个线程来打印hello,当按下enter,停止打印。】、
在不使用静态变量的境况下使用指针函数做引用传参,正好复习一下昨天学习的内容:
void printHello(bool& judgeCon){
using namespace std::literals::chrono_literals;
std::cout << "started thread id = " << std::this_thread::get_id() << std::endl;
while (judgeCon) {
std::cout << "hello" << std::endl;
std::this_thread::sleep_for(1s);
//std::this_thread使用它来给当前线程下载命令
}
}
int main() {
bool judgeCon = true;
//接收函数指针
std::thread worker(printHello,std::ref(judgeCon));
std::cin.get();
judgeCon = false;
worker.join();
std::cout << "started thread id = " << std::this_thread::get_id() << std::endl;
std::cin.get();
}
其中std::this_thread使用它来给当前线程下达命令。
计时
大部分情况都使用这个库来进行计时,
#include<thread>
#include<chrono>
using namespace std::literals::chrono_literals;
auto start = std::chrono::high_resolution_clock::now();
std::this_thread::sleep_for(1s);
auto end = std::chrono::high_resolution_clock::now();
std::cout << (float)(end - start).count() << std::endl;
在实际使用中,可以借用结构体生命周期的特殊之处来完成计时器的构建:
struct Timer1
{
std::chrono::steady_clock::time_point start, end;
Timer1() {
auto start = std::chrono::high_resolution_clock::now();
}
~Timer1() {
auto end = std::chrono::high_resolution_clock::now();
std::cout << (float)(end - start).count() << std::endl;
}
};
void printAll() {
Timer1();
for (int tmp : {0, 1, 2, 3, 4, 5}) {
std::cout << tmp << "\n";
}
}
#main
printAll();
但是不知道为什么构造函数执行结束之后就执行了析构函数。
使用std::endl
会让代码变慢,因为它不仅在输出流中插入换行符,还会执行额外的操作来清空缓冲区。具体分析如下:
- 插入换行:
std::endl
和" "
都能在输出流中插入换行符。 - 刷新缓冲区:
std::endl
会立即刷新输出缓冲区。这意味着所有的缓冲数据都会被发送到目标设备(如屏幕或文件),并且缓冲区会被清空。这个刷新过程需要时间,特别是当数据量很大时,它会显著增加I/O操作的时间。
相比之下,使用" "
仅仅插入了一个换行符,不会触发缓冲区的刷新,因此在某些情况下可以提供更快的输出速度。然而,如果不手动刷新缓冲区,输出的数据可能会滞留在缓冲区中,直到缓冲区被填满或程序结束。
总的来说,如果对输出速度有较高要求,可以考虑使用" "
来代替std::endl
,并在适当的时机手动调用std::cout.flush()
或等待缓冲区自然刷新,以达到既快速又确保数据完整的效果。