请让我开始,我知道从构造函数/析构函数中调用虚函数是一种不好的做法。然而,这样做的行为,虽然它可能令人困惑或不是用户所期望的,但仍然是明确定义的。
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) #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 语句返回是否可以防止异常被重新抛出?
我正在阅读 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函数来确保所有权被放弃。
我错过了什么吗?
我花了一些时间才得到错误,但仍然不知道如何解决
正如代码中出现的那样,只有一个构造函数调用,但它调用了两次析构函数
代码:
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)
怎么会这样?编译器至少应该为我生成一个警告吗?你怎么认为?
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 …