小编zxy*_*122的帖子

为什么在构造函数中调用虚拟方法并绑定虚拟方法然后稍后调用它会产生不同的结果?

这是我的代码片段:

class Base {
  public:

  Base() {
    foo();
    bind();
  }

  virtual void foo() {
    std::cout << "base foo\n";
  }

  void bind() {
    fn = std::bind(&Base::foo, this);
  };

  std::function<void()> fn;
};

class Derived : public Base {
  public:

  void foo() override {
    std::cout << "derived foo\n";
  }

  void bind()  {
  }

  int val;    
};

int main() {
  Base* p = new Derived();
  p->fn();
}
Run Code Online (Sandbox Code Playgroud)

输出是:

class Base {
  public:

  Base() {
    foo();
    bind();
  }

  virtual void foo() {
    std::cout << "base …
Run Code Online (Sandbox Code Playgroud)

c++ constructor virtual-functions stdbind

7
推荐指数
2
解决办法
148
查看次数

在右值参考参数上使用std :: move的原因

我正在读一本关于用C ++实现的数据结构的书,我不明白代码片段吗?它是向量类的一部分

void push_back(object &&x) {
        //do something
        objects[size++] = std::move(x);
    }
Run Code Online (Sandbox Code Playgroud)

我知道std::move返回对象的右值引用,但是push_back成员函数已经具有右值引用x作为参数,std::move这里不是不必要的吗?

另一个问题是,如果我们有一个类对象的右值引用,std::move如果要调用move而不是copy right 还是需要在其成员上使用它?像下面的代码:

A& operator=(A&& other) {
     member = std::move(other.member);
     return *this;
}
Run Code Online (Sandbox Code Playgroud)

c++ rvalue-reference move-semantics c++11 value-categories

5
推荐指数
2
解决办法
106
查看次数

将右值传递给 std::move 并将右值引用绑定到它会在 ASAN 中生成 stack-use-after-scope 错误

考虑这个代码片段

#include <iostream>
int foo() {
  int a;
  return a;
}
int main() {
  auto &&ret = std::move(foo());
  std::cout << ret;
}
Run Code Online (Sandbox Code Playgroud)

使用ASAN编译g++ -fsanitize=address -fno-omit-frame-pointer -g -std=c++17 main.cpp -o main,运行./main显示错误

==57382==ERROR: AddressSanitizer: stack-use-after-scope on address 0x00016b3cb480 at pc 0x000104a37e68 bp 0x00016b3cb450 sp 0x00016b3cb448
READ of size 4 at 0x00016b3cb480 thread T0
    #0 0x104a37e64 in main main.cpp:8
    #1 0x104a75084 in start+0x200 (dyld:arm64e+0x5084)
Run Code Online (Sandbox Code Playgroud)

但是如果我在 auto 之后删除引用,这段代码可以编译并运行,而不会出现 ASAN 给出的错误。我不明白的是,如果std::move返回对给定对象的引用,那么该对象(foo()在本例中是临时创建的)将在函数调用返回后被销毁std::move,因此无论它是绑定到右值引用还是分配给新值应该无效,因为该临时值在移动操作后已经被销毁,对吗?那么为什么 ASAN 在第二种情况下不会给出错误。

- - …

c++ stdmove

4
推荐指数
2
解决办法
188
查看次数

C++ 顺序一致性并且发生在关系之前

    #include <atomic>
    #include <thread>
    #include <assert.h>
    std::atomic<bool> x,y;
    std::atomic<int> z;
    void write_x()
    {
        x.store(true,std::memory_order_seq_cst); // 1
    }
    void write_y()
    {
        y.store(true,std::memory_order_seq_cst); // 2
    }
    void read_x_then_y()
    {
        while(!x.load(std::memory_order_seq_cst)); // 3
        if(y.load(std::memory_order_seq_cst)) // 4
            ++z;
    }
    void read_y_then_x()
    {
        while(!y.load(std::memory_order_seq_cst)); // 5
        if(x.load(std::memory_order_seq_cst)) // 6
            ++z;
    }
    int main() {
        x=false;
        y=false;
        z=0;
        std::thread a(write_x);
        std::thread b(write_y);
        std::thread c(read_x_then_y);
        std::thread d(read_y_then_x);
        a.join();
        b.join();
        c.join();
        d.join();
        assert(z.load()!=0); 
    }
Run Code Online (Sandbox Code Playgroud)

在《C++ Concurrency in Action》一书中,作者在谈论顺序一致性时给出了这个例子,并说assert永远不能触发,因为

[1] 或 [2] 必须首先发生...并且如果一个线程看到 x==true 然后随后看到 y==false,这意味着按照总顺序,对 …

c++ multithreading atomic memory-model stdatomic

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