C++ 用户定义类和std类之间有区别吗?

C++ 用户定义类和std类之间有区别吗?,c++,oop,c++-standard-library,C++,Oop,C++ Standard Library,据我所知,调用构造函数/析构函数的唯一区别取决于实例化顺序。但是“正常”用户类和std中的类之间还有什么区别吗 假设我有一个名为myStackOverflow的类,然后我实例化了这个类的一个对象。我在同一范围内还有一个类型为std::thread的对象。调用这些对象的构造函数或析构函数的方式有什么不同吗 我问这个问题的主要原因是,根据(第30.3.2.3节)join()没有在线程析构函数中调用。你可以阅读“为什么”。但是在stackoverflow的回答中提到了在另一个类中包装std::thre

据我所知,调用构造函数/析构函数的唯一区别取决于实例化顺序。但是“正常”用户类和std中的类之间还有什么区别吗

假设我有一个名为
myStackOverflow
的类,然后我实例化了这个类的一个对象。我在同一范围内还有一个类型为
std::thread
的对象。调用这些对象的构造函数或析构函数的方式有什么不同吗

我问这个问题的主要原因是,根据(第30.3.2.3节)
join()
没有在线程析构函数中调用。你可以阅读“为什么”。但是在stackoverflow的回答中提到了在另一个类中包装
std::thread
,然后在这个新包装类的析构函数中调用
join()
。我不明白这怎么能解决任何问题。析构函数仍然是析构函数,在
std::thread
的析构函数中调用
join()
的危险仍然存在


唯一有意义的方法是调用这两种不同类型的析构函数之间的区别。< /P> < P> OK @ Ali,让我们简要地概述一些事物(术语)。
名称空间std
-是一个简单的名称空间,如:

namespace my_namespace {
    int my_integer;
};
它为程序员提供了大量有用的类,由超级强大的类编写,并且,正如您所理解的,它应该尽可能灵活(后面的“语句1”),因为不同的人有不同的需求

当然,它遵循C++标准的一般规则,内容也一样。


现在,让我们谈谈您想要的
std::thread

它是一个简单的类,表示。它允许您在“外层空间”中执行功能,并与我们抽象的“外层空间”保持联系,它还处理一些数据:

  • _id-线程id
  • _句柄-秘密变量,它是与“外部空间”通信的密钥
  • 当然,它保存了一些数据 关于执行状态(是否有任何实体现在在中的某个位置执行 钥匙引导我们到达的“外层空间”)
如果您查阅更多详细信息并牢记我们的“声明1”,您将注意到以下信息:

  • std::thread
    对象也可能处于不表示任何线程的状态”
  • 没有两个
    std::thread
    对象可以代表同一个执行线程;
    std::thread
    不可复制构造或复制分配,尽管它是可移动构造和可移动分配的

现在您应该得出一个结论,即
std::thread
变量和执行实体是分开的,但是尝试删除附加到执行实体的
std::thread
变量会引发异常

但是当实体完成执行时,
std::thread
变量保持活动状态,并且可以附加到任何其他实体

对于这些需求,有以下方法:

 join() // waits for a thread to finish its execution
 // if it is attached to something, the code execution will not go futher until our entity finishes its execution.

 detach() // permits the thread to execute independently from the thread handle 
// detaches our std:: thread variable from executing entity, now our entity lives its own life. std::thread variable may be removed while the entity keeps alive

joinable() // checks whether the thread is joinable, i.e. potentially running in parallel context
// if thread is attached to something which is executing now, it returns true, otherwise false

下面是一些代码示例,可以消除您的误解:

#include <iostream>
#include <thread>
#include <chrono>

using namespace::std;

void some_func1() {
    cout << "some_func1 thread started " << endl;
    this_thread::sleep_for(chrono::seconds(2));
    cout << "some_func1 thread finished " << endl;
}

void some_func2() {
    cout << "some_func2 thread started " << endl;
    this_thread::sleep_for(chrono::seconds(2));
    cout << "some_func2 thread finished " << endl;
}


int main() {    

    thread some_thread;

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    some_thread = thread(some_func1);

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    some_thread.detach();

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    this_thread::sleep_for(chrono::seconds(1)); 

    some_thread = thread(some_func2);

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    some_thread.join();

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;
}

//  Output is:
//  Is some_thread joinable: 0
//  some_func1 thread started
//  Is some_thread joinable: 1
//  Is some_thread joinable: 0
//  some_func2 thread started
//  Is some_thread joinable: 1
//  some_func1 thread finished
//  some_func2 thread finished
//  Is some_thread joinable: 0
//  Press any key to continue . . .


现在,我希望它对你来说是清晰的,如果你知道变量何时移除:d

“p>好”Ali,让我们简单地概述一些事物(术语)。
名称空间std
-是一个简单的名称空间,如:

namespace my_namespace {
    int my_integer;
};
它为程序员提供了大量有用的类,由超级强大的类编写,并且,正如您所理解的,它应该尽可能灵活(后面的“语句1”),因为不同的人有不同的需求

当然,它遵循C++标准的一般规则,内容也一样。


现在,让我们谈谈您想要的
std::thread

它是一个简单的类,表示。它允许您在“外层空间”中执行功能,并与我们抽象的“外层空间”保持联系,它还处理一些数据:

  • _id-线程id
  • _句柄-秘密变量,它是与“外部空间”通信的密钥
  • 当然,它保存了一些数据 关于执行状态(是否有任何实体现在在中的某个位置执行 钥匙引导我们到达的“外层空间”)
如果您查阅更多详细信息并牢记我们的“声明1”,您将注意到以下信息:

  • std::thread
    对象也可能处于不表示任何线程的状态”
  • 没有两个
    std::thread
    对象可以代表同一个执行线程;
    std::thread
    不可复制构造或复制分配,尽管它是可移动构造和可移动分配的

现在您应该得出一个结论,即
std::thread
变量和执行实体是分开的,但是尝试删除附加到执行实体的
std::thread
变量会引发异常

但是当实体完成执行时,
std::thread
变量保持活动状态,并且可以附加到任何其他实体

对于这些需求,有以下方法:

 join() // waits for a thread to finish its execution
 // if it is attached to something, the code execution will not go futher until our entity finishes its execution.

 detach() // permits the thread to execute independently from the thread handle 
// detaches our std:: thread variable from executing entity, now our entity lives its own life. std::thread variable may be removed while the entity keeps alive

joinable() // checks whether the thread is joinable, i.e. potentially running in parallel context
// if thread is attached to something which is executing now, it returns true, otherwise false

下面是一些代码示例,可以消除您的误解:

#include <iostream>
#include <thread>
#include <chrono>

using namespace::std;

void some_func1() {
    cout << "some_func1 thread started " << endl;
    this_thread::sleep_for(chrono::seconds(2));
    cout << "some_func1 thread finished " << endl;
}

void some_func2() {
    cout << "some_func2 thread started " << endl;
    this_thread::sleep_for(chrono::seconds(2));
    cout << "some_func2 thread finished " << endl;
}


int main() {    

    thread some_thread;

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    some_thread = thread(some_func1);

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    some_thread.detach();

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    this_thread::sleep_for(chrono::seconds(1)); 

    some_thread = thread(some_func2);

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;

    some_thread.join();

    cout << "Is some_thread joinable: " << some_thread.joinable() << endl;
}

//  Output is:
//  Is some_thread joinable: 0
//  some_func1 thread started
//  Is some_thread joinable: 1
//  Is some_thread joinable: 0
//  some_func2 thread started
//  Is some_thread joinable: 1
//  some_func1 thread finished
//  some_func2 thread finished
//  Is some_thread joinable: 0
//  Press any key to continue . . .


现在我希望它对你们来说是非常清晰的,如果你们理解变量移除的时间:D

没有区别,我认为你们过于简单化和错误表述了。如果您编写自己的代码,那么您可以决定在您的情况下加入析构函数是否合适。但这并不意味着加入析构函数对于任何情况下的每个用户都是合适的。在自动加入是一个问题的情况下,您当然不会使用加入包装器。@Ali:这是一个非常宽泛的问题,无法得到任何简洁的答案。您可以分析需求并设计实现,在这个过程中,您将发现并发模型应该是什么样子的。我们的展台上没有
自动解决所有问题