小编Gil*_*ils的帖子

虚拟表创建线程安全吗?

请让我开始,我知道从构造函数/析构函数中调用虚函数是一种不好的做法。然而,这样做的行为,虽然它可能令人困惑或不是用户所期望的,但仍然是明确定义的。

struct Base
{
    Base()
    {
        Foo();
    }
    virtual ~Base() = default;
    virtual void Foo() const
    {
        std::cout << "Base" << std::endl;
    }
};

struct Derived : public Base
{
    virtual void Foo() const
    {
        std::cout << "Derived" << std::endl;
    }
};

int main(int argc, char** argv) 
{
    Base base;
    Derived derived;
    return 0;
}

Output:
Base
Base
Run Code Online (Sandbox Code Playgroud)

现在,回到我真正的问题。如果用户从不同线程的构造函数中调用虚函数会发生什么。有竞争条件吗?它是未定义的吗?或者换句话说。编译器设置 vtable 是线程安全的吗?

例子:

struct Base
{
    Base() :
        future_(std::async(std::launch::async, [this] { Foo(); }))
    {
    }
    virtual ~Base() = default;

    virtual void …
Run Code Online (Sandbox Code Playgroud)

c++ race-condition object-lifetime language-lawyer

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

使用 function-try-block 时 Visual Studio 中发出 C4297 警告(假定函数不会引发异常,但确实引发了异常)

#include <exception>

struct FOO
{
  ~FOO() try
  {
    throw std::exception();
  }
  catch (...)
  {
    return; // Shall prevent the exception from being rethrown?
  }
};
Run Code Online (Sandbox Code Playgroud)

在 Visual Studio 中构建此代码会触发 C4297 警告(假设函数不会引发异常,但确实引发了异常)。

到达析构函数上的函数 try 块的 catch 子句的末尾也会自动重新抛出当前异常,就像通过 throw; 一样,但允许使用 return 语句引自 cppreference.com

我对这句话的理解正确吗?从 catch 语句返回是否可以防止异常被重新抛出?

我记录了一个错误,但他们将其作为重复项关闭。另一个错误没有,return statement但我认为这很重要。

实例

c++ exception language-lawyer

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

在移动“unique_ptr”时,我们真的需要确保放弃所有权吗?

我正在阅读 Nicolai M. Josuttis 的《C++ Move Semantics - The Complete Guide》一书(恕我直言,这本书相当不错),我不确定我是否同意其中一个示例中的评论。

引用(来自 6.1.2 - 移出对象的保证状态):

类似的代码可用于释放唯一指针使用的对象的内存:

draw(std::move(up));  // the unique pointer might or might not give up ownership
up.reset();           // ensure we give up ownership and release any resource
Run Code Online (Sandbox Code Playgroud)

让我们假设up变量确实是unique_ptr,并且draw函数接收unique_ptr值(否则,将指针移动到“passed-by-ref”函数有什么意义)。

reset我知道调用“移出”对象是合法的。但我不明白的是为什么它是“必需的”,以便“确保我们放弃所有权并释放任何资源”以及“唯一指针可能会或可能不会”是如何可能的放弃所有权”怎么可能?

毕竟,unique_ptrs 无法复制,而且整个想法是它们仅保证一种所有权。

因此,据我所知,如果我的两个假设是正确的,则无需调用该reset函数来确保所有权被放弃。

我错过了什么吗?

c++ move move-semantics c++11

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

有一个构造函数,但有两个析构函数

我花了一些时间才得到错误,但仍然不知道如何解决

正如代码中出现的那样,只有一个构造函数调用,但它调用了两次析构函数

代码:

struct A
{
  A()
  {
      std::cout << "C'tor" << std::endl;
  }

  A(A&&)
  {
      std::cout << "M'tor" << std::endl;
  }

  A(const A&) = delete;
  A& operator=(const A&) = delete;
  A& operator=(A&&) = delete;

  ~A()
  {
      std::cout << "D'tor" << std::endl;
  }
};

int main()
{
    auto lambda = [](int i){
        A a;
        if (i == 0)
            return std::move(a);
    };

    lambda(1);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

输出:

C'tor                                                                                                                                                                        
D'tor                                                                                                                                                                        
D'tor
Run Code Online (Sandbox Code Playgroud)

怎么会这样?编译器至少应该为我生成一个警告吗?你怎么认为?

c++ oop gcc compilation

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

Returning a pointer to a member and assigning it to a reference. Is it legal?

I'm reviewing code and which looks kind of wrong to me. I know it can be written in another way and I know it is probably useless to write it this way. Still, I was surprised that the compiler didn't generate any error/warning so I wonder if it is legal and why.

struct A
{
    int val = 0;
    int* GetVal() {
        return &val;
    }
};

void main()
{
    A a;
    int* const& r = a.GetVal();
}
Run Code Online (Sandbox Code Playgroud)

AFAIK, a reference …

c++

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