这是来自C++ 11标准sec 12.7.4.这相当令人困惑.
B::B未定义?不是它只是打电话a.A::f?4构造函数,包括虚函数(10.3),可以在构造或销毁期间调用(12.6.2).当从构造函数或析构函数直接或间接调用虚函数时,包括在构造或销毁类的非静态数据成员期间,以及调用所适用的对象是正在构造的对象(称为x)或者破坏,被调用的函数是构造函数或析构函数类中的最终覆盖,而不是在更多派生类中覆盖它.如果虚函数调用使用显式类成员访问(5.2.5)并且对象表达式引用x的完整对象或该对象的基类子对象之一但不是x或其基类子对象之一,则行为未定义.[例如:
Run Code Online (Sandbox Code Playgroud)struct V { virtual void f(); virtual void g(); }; struct A : virtual V { virtual void f(); }; struct B : virtual V { virtual void g(); B(V*, A*); }; struct D : A, B { virtual void f(); virtual void g(); D() : B((A*)this, this) { } }; B::B(V* v, A* a) { f(); // calls V::f, not A::f g(); // calls B::g, not D::g v->g(); // …
是否有可能有一些抽象接口的部分实现,然后通过使用多个继承将这些部分实现收集到一个具体的类中?
我有以下示例代码:
#include <iostream>
struct Base
{
virtual void F1() = 0;
virtual void F2() = 0;
};
struct D1 : Base
{
void F1() override { std::cout << __func__ << std::endl; }
};
struct D2 : Base
{
void F2() override { std::cout << __func__ << std::endl; }
};
// collection of the two partial implementations to form the concrete implementation
struct Deriv : D1, D2
{
using D1::F1; // I …Run Code Online (Sandbox Code Playgroud) 我在使用boost enable_shared_from_this和多重继承时遇到了一些麻烦.
该场景可以描述如下:
类A实现了一些功能,应该继承enable_shared_from_this
类B实现了另一个功能,应该继承enable_shared_from_this
类D从A和B(class D : public A, public B {})继承功能
当我B从类中使用一些类功能时,D我得到了一个异常(bad_weak_ptr)
继承enable_shared_from_this课程D对我来说不是一个选择
我不知道如何解决这个问题.
哦,我正在使用Visual C++ 2010.
哪些代码有UB(具体来说,哪些违反了严格的别名规则)?
void a() {
std::vector<char> v(sizeof(float));
float *f = reinterpret_cast<float *>(v.data());
*f = 42;
}
void b() {
char *a = new char[sizeof(float)];
float *f = reinterpret_cast<float *>(a);
*f = 42;
}
void c() {
char *a = new char[sizeof(float)];
float *f = new(a) float;
*f = 42;
}
void d() {
char *a = (char*)malloc(sizeof(float));
float *f = reinterpret_cast<float *>(a);
*f = 42;
}
void e() {
char *a = (char*)operator new(sizeof(float));
float *f = reinterpret_cast<float *>(a);
*f = …Run Code Online (Sandbox Code Playgroud) 以下是典型的实现type_info::operator==:
#if _PLATFORM_SUPPORTS_UNIQUE_TYPEINFO
bool operator==(const type_info& __rhs) const {
return __mangled_name == __rhs.__mangled_name;
}
#else
bool operator==(const type_info& __rhs) const {
return __mangled_name == __rhs.__mangled_name ||
strcmp(__mangled_name, __rhs.__mangled_name) == 0;
}
#endif
Run Code Online (Sandbox Code Playgroud)
在libstdc ++中它受控制__GXX_MERGED_TYPEINFO_NAMES,
在libc ++中_LIBCPP_NONUNIQUE_RTTI_BIT,
MSVC总是比较字符串.
什么是不比较字符串的平台?
以下非常简单的代码将无法编译
#include <vector>
#include <string>
namespace Foobar {
struct Test {
std::string f;
std::uint16_t uuid;
};
}
bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
}
int main(){
std::vector<Foobar::Test> a;
std::vector<Foobar::Test> b;
if(a==b){
}
return 0;
}
Run Code Online (Sandbox Code Playgroud)
不会编译我的任何编译器.
而以下
#include <vector>
#include <string>
namespace Foobar {
struct Test {
std::string f;
std::uint16_t uuid;
};
bool operator==(const Foobar::Test& lhs, const Foobar::Test& rhs){
return lhs.f == rhs.f && lhs.uuid == rhs.uuid;
}
}
int …Run Code Online (Sandbox Code Playgroud) c++ dependent-name template-function name-lookup argument-dependent-lookup
我很好奇,如果标记现有的派生C++类final以允许去虚拟化优化将在使用C++ 11时改变ABI.我的期望是,它应该有没有影响,因为我认为这主要是提示编译器有关它如何能够优化虚函数,因此我看不到任何方式,它会改变结构或V表的大小,但也许我错过了什么?
我知道这里更改API,以便从这个派生类进一步派生的代码将不再起作用,但我只关注这个特殊情况下的ABI.
C 2018 5.1.2.3 6说:
符合实施的最低要求是:
根据抽象机器的规则严格评估对易失性对象的访问.
在程序终止时,写入文件的所有数据应与根据抽象语义执行程序的结果相同.
交互设备的输入和输出动态应按照7.21.3的规定进行.这些要求的目的是尽快出现无缓冲或行缓冲输出,以确保在程序等待输入之前实际出现提示消息.
这是该程序的可观察行为.
从表面上看,这不包括程序的退出状态.
关于exit(status),7.22.4.4 5说:
最后,控制权返回给主机环境.如果值
status为零或EXIT_SUCCESS,则返回状态成功终止的实现定义形式.如果值status是EXIT_FAILURE,地位的实现定义的形式成功终止返回.否则返回的状态是实现定义的.
标准没有告诉我们这是可观察行为的一部分.当然,这种exit行为纯粹是C的抽象机器的描述是没有意义的; 除非在环境中可观察到,否则向环境返回值没有意义.所以我的问题不在于退出状态是否可观察到这是否是C标准对可观察行为的定义中的缺陷.或者标准中的其他地方是否有适用的文字?
在C ++中,如果我有一个类:
class Example {
static int s_One, s_Two;
...
};
Run Code Online (Sandbox Code Playgroud)
语言是否明确定义了s_Two它也是静态的?
换句话说,static关键字扩展int是随处可见的,还是*仅适用于一个变量?
据我所知,编译器从不优化声明为的变量volatile.但是,我有一个像这样声明的数组.
volatile long array[8];
Run Code Online (Sandbox Code Playgroud)
不同的线程读写它.数组的元素仅由其中一个线程修改,并由任何其他线程读取.但是,在某些情况下,我注意到即使我从一个线程修改一个元素,读取它的线程也不会注意到这个变化.它继续读取相同的旧值,就好像编译器已将其缓存在某处.但是编译器本身不应该缓存volatile变量,对吧?那怎么会发生这种情况.
注意:我不是volatile用于线程同步,所以请停止给我答案,如使用锁或原子变量.我知道volatile,atomic变量和互斥量之间的区别.另请注意,该体系结构是x86,具有主动缓存一致性.在我认为变量被其他线程修改后,我也读了很长时间.即使经过很长一段时间,阅读线程也看不到修改后的值.