小编cur*_*guy的帖子

如果继承不是公开的而不是出错,为什么 enable_shared_from_this 会崩溃

我在一个项目中使用了 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)

c++ shared-ptr private-inheritance enable-shared-from-this

2
推荐指数
1
解决办法
260
查看次数

最佳可行的转换功能

在以下程序中,应选择哪个(如果有)转换功能,为什么?

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

2
推荐指数
1
解决办法
82
查看次数

转换为char *后写入std :: atomic

对不起,如果我的怀疑太幼稚。但我有一个类型转换难度std::atomicchar*类型。是强制转换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类型)。

谢谢 :)

c++ memory-layout reinterpret-cast stdatomic

2
推荐指数
1
解决办法
92
查看次数

如何在C ++中单独锁定unordered_map元素

我有一个unordered_map我希望可以被多个线程访问的方法,但是用互斥锁锁定整个过程太慢了。

为了解决这个问题,我在的每个元素中放置了一个互斥锁unordered_map

class exampleClass{
    std::mutex m;
    int data;
};

std::unordered_map<int,exampleClass> exampleMap;
Run Code Online (Sandbox Code Playgroud)

问题是我无法安全地擦除元素,因为要破坏互斥锁必须将其解锁,但是如果解锁,则另一个线程可以将其锁定并在破坏期间写入或读取该元素。

c++ multithreading mutex unordered-map

2
推荐指数
1
解决办法
153
查看次数

对象和实例的定义

根据什么是C ++中的类和对象?

一个类就像一个蓝图,一个对象就像是用该蓝图建造的房屋。

您可以拥有许多具有相同布局/平面图的房屋(读取类),但每个房屋都是其自己的实例(读取对象)。每个人都有自己的所有者,家具等。

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 …

c++ class definition object object-lifetime

2
推荐指数
1
解决办法
68
查看次数

如何重载虚拟操作员

我有一个简单的继承结构:

  • 基本<-派生1
  • 基数<-衍生2

我想重载<<和>>运算符以输入和打印对象Derived1Derived2类中的数据,作为对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班级中,并在Derived1Derived2班级中覆盖它们?

我想做这样的事情:

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)

c++ virtual operator-overloading

2
推荐指数
1
解决办法
48
查看次数

线程安全是否意味着没有竞争条件?

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

2
推荐指数
1
解决办法
92
查看次数

为什么std :: atomic &lt;std :: string&gt;给出平凡的可复制错误?

我的程序很简单,我想使用原子类型。可以使用intdouble但不能使用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>正确使用?

c++ atomic stdstring thread-safety stdatomic

2
推荐指数
1
解决办法
92
查看次数

std::mutex 阻止线程修改什么?

mutex.lock()或 时,内存的哪一部分被锁定.try_lock(),是只是函数还是整个程序被锁定?

c++ multithreading mutex thread-safety

2
推荐指数
1
解决办法
1357
查看次数