我在一个项目中使用了 shared_ptr。有一次,我不得不将原始指针存储为 void,然后在传递 void* 的回调中将其转换回其 shared_ptr 形式。但由于某种原因,代码不断崩溃。我不明白为什么,因为我没有收到任何编译器错误或警告。但我注意到,当我继承自时,std::enable_shared_from_this
我并没有将其分配为公共继承。这就是导致崩溃的原因。
我写了一个示例代码,我只是想知道它为什么会发生。
#include <memory>
#include <iostream>
class TestShared : public std::enable_shared_from_this<TestShared>{
private:
int32_t id;
public:
TestShared(int32_t id){
this->id = id;
}
std::shared_ptr<TestShared> getshared(){
return shared_from_this();
}
int32_t getid(){
return id;
}
};
int main(){
std::shared_ptr<TestShared> ts(new TestShared(0xFF));
void* tsp = ts.get();
std::shared_ptr<TestShared> tsn = ((TestShared*)tsp)->getshared();
std::cout << std::hex << tsn->getid();
return 0;
}
Run Code Online (Sandbox Code Playgroud)
所以该代码将执行并运行良好,我得到了预期的结果。
但是当我从继承中删除 public 时:
#include <memory>
#include <iostream>
class TestShared : std::enable_shared_from_this<TestShared>{
private:
int32_t id;
public:
TestShared(int32_t id){
this->id …
Run Code Online (Sandbox Code Playgroud) 在以下程序中,应选择哪个(如果有)转换功能,为什么?
int r;
struct B {};
struct D : B {};
struct S {
D d;
operator D&(){r=1; return d;} // #1
operator B&(){r=2; return d;} // #2
};
int main() {
S s;
B& b = s;
return r;
}
Run Code Online (Sandbox Code Playgroud)
gcc和clang选择均选择转换功能#2。但为什么?
标准说:
(1)在[dcl.init.ref]中指定的条件下,可以将引用直接绑定到将转换函数应用于初始化程序表达式的结果。重载解析用于选择要调用的转换函数。假设“对cv1 T的引用”是要初始化的引用的类型,而“ cv S”是初始化程序表达式的类型,其中S为类类型,则按以下方式选择候选函数:
(1.1)-考虑S的转换函数及其基类。那些未隐藏在S中且产生类型“对cv2 T2的左值引用”(初始化对函数的左值引用或右值引用时)或“ cv2 T2”或“对cv2 T2的右值引用”的非显式转换函数将右值引用或左值引用初始化为函数),其中“ cv1 T”与“ cv2 T2”的引用兼容)是候选函数。对于直接初始化,未隐藏在S中的那些显式转换函数会产生类型“对cv2 T2的左值引用”(初始化对函数的左值引用或右值引用)或“对cv2 T2的右值引用”(当初始化对函数的右值引用或左值引用),
(2)参数列表有一个参数,它是初始化器表达式。[?注:此参数将与转换函数的隐式对象参数进行比较。-?尾注?]
这里我们有两个候选函数#1和#2。两者都可行-如果删除其中之一,程序仍会编译。这两个转换函数仅采用隐式参数,并且具有相同的cv和ref限定。因此,没有一个应该是最可行的,并且该程序也不应编译。为什么编译?
c++ language-lawyer overload-resolution implicit-conversion reference-binding
对不起,如果我的怀疑太幼稚。但我有一个类型转换难度std::atomic
要char*
类型。是强制转换std::atomic to char
有效吗?
我可以写这样的类型转换变量。我确信当线程试图将变量写入变量时不会有多线程读/写操作(我知道,当该变量没有并发访问时,就不需要使用原子)。
std::atomic<uint8_t>* data_;
char *data = reinterpret_cast<char*>(data_);
*data |= mask;
Run Code Online (Sandbox Code Playgroud)
安全吗?
编辑:我不确定是否值得一提。在我的代码中
char *raw;
// variable raw is allocated
std::atomic<uint8_t>* data_ = reinterpret_cast<std::atomic<uint8_t>*>(raw);
Run Code Online (Sandbox Code Playgroud)
上面是std::atomic< uint8_t>
创建方法的方式(作为char和type强制转换为std :: atomic类型)。
谢谢 :)
我有一个unordered_map
我希望可以被多个线程访问的方法,但是用互斥锁锁定整个过程太慢了。
为了解决这个问题,我在的每个元素中放置了一个互斥锁unordered_map
:
class exampleClass{
std::mutex m;
int data;
};
std::unordered_map<int,exampleClass> exampleMap;
Run Code Online (Sandbox Code Playgroud)
问题是我无法安全地擦除元素,因为要破坏互斥锁必须将其解锁,但是如果解锁,则另一个线程可以将其锁定并在破坏期间写入或读取该元素。
一个类就像一个蓝图,一个对象就像是用该蓝图建造的房屋。
您可以拥有许多具有相同布局/平面图的房屋(读取类),但每个房屋都是其自己的实例(读取对象)。每个人都有自己的所有者,家具等。
Note that there are also objects whose blueprint is not a class (e.g. integers).
In summary, there are different types of object (e.g. int, float, etc.). You can create user-defined types, called 'classes'.
In C++, the term object is used for instances of any type, including classes and fundamental types.
However, according to http://www.cplusplus.com/doc/tutorial/classes/
An object is an instantiation of a class. In terms of variables, a class would be the type, and an object …
我有一个简单的继承结构:
我想重载<<和>>运算符以输入和打印对象Derived1
和Derived2
类中的数据,作为对Base
类的引用。
我可以声明某种虚函数吗?像这样 :
virtual std::ostream& operator<<(std::ostream& os, const Base& obj) = 0;
virtual std::istream& operator>>(std::istream& is, Base& obj) = 0;
Run Code Online (Sandbox Code Playgroud)
在我的Base
班级中,并在Derived1
和Derived2
班级中覆盖它们?
我想做这样的事情:
std::vector<Base&> a;
... push reference to Derived1 and Derived2 objects ...
for (auto i = a.begin(); i != a.end(); ++i) std::cin >> (*i);
for (auto i = a.begin(); i != a.end(); ++i) std::cout << (*i);
Run Code Online (Sandbox Code Playgroud) ConcurrentHashMap是线程安全的,但是会发生竞争情况,因为据我了解,仅映射的一部分被锁定并且仅用于写操作,这意味着如果同时存在读取操作,则将存在竞争条件。
但是我也喜欢在这里阅读https://en.wikipedia.org/wiki/Thread_safety
Thread safe: Implementation is guaranteed to be free of race conditions when accessed by multiple threads simultaneously.
Run Code Online (Sandbox Code Playgroud)
我可以说ConcurrentHashMap是线程安全的,但没有完全同步吗?这里正确的术语是什么?
java multithreading thread-safety race-condition thread-synchronization
我的程序很简单,我想使用原子类型。可以使用int
,double
但不能使用std::string
。
#include <iostream>
#include <atomic>
#include <string>
int main()
{
std::atomic<int> test(0); // works
std::cout<<test; // will print 0
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果我更改为
std::atomic<std::string> test("0");
Run Code Online (Sandbox Code Playgroud)
它将给出此错误
/ usr / include / c ++ / 6 / atomic:在'struct std :: atomic>'的实例中:main.cpp:16:34:
从此处需要/ usr / include / c ++ / 6 / atomic:178:7:错误:静态断言失败:std :: atomic需要一个普通可复制类型static_assert(__ is_trivially_copyable(_Tp),^ ~~~~~~~~~~~~~
我已经使用C ++ 17,C ++ 14和C ++ 11测试了该代码。遵循此线程std :: atomic <std :: string>是否正常工作?原子字符串应该可以正常工作,但是出现了这个错误。这是什么原因呢?以及如何std::atomic<std::string>
正确使用?
mutex
当.lock()
或 时,内存的哪一部分被锁定.try_lock()
,是只是函数还是整个程序被锁定?
从聚合初始化,将指针设置为 struct member,以下代码合法:
struct S
{
int a;
int* aptr;
};
S s = { 3, &s.a };
Run Code Online (Sandbox Code Playgroud) c++ initialization object-lifetime language-lawyer aggregate-initialization