- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
由于情况复杂(在前面的问题 Constructing an object to return by value elsewhere 中解释过)我想从函数 X 按值返回一个对象,但在 X 间接调用的另一个函数 Y 中创建它。在它们之间有调用中的第 3 方代码不会合作传递对象的堆栈。 X 只能将指针传递给 Y 并接收返回的指针。
我想出了一个使用 placement new 的解决方案,但主要担心它是否可移植、不会调用任何未定义的行为并安全地处理分配的对象。也欢迎任何避免不必要的拷贝的改进。这是一个尽可能精简的完整测试程序:
#include <new>
#include <type_traits>
#include <cstdio>
class A {
public:
A() {
printf("Create A @ %p\n", this);
}
A(const A &other) {
printf("Copy A @ %p\n", this);
printf("From another A %s @ %p\n", other.valid ? "OK" : "NOT OK", &other);
valid = other.valid;
}
A(A &&other) {
printf("Move A @ %p\n", this);
printf("From another A %s @ %p\n", other.valid ? "OK" : "NOT OK", &other);
valid = other.valid;
}
~A() {
printf("Destroy A %s @ %p\n", valid ? "OK" : "NOT OK", this);
valid = false;
}
void bar() {printf("Hello, World! (A %s @ %p)\n", valid ? "OK" : "NOT OK", this);}
bool valid = true;
};
class WrapA {
public:
WrapA() {printf("Create wrapper! (A @ %p)\n", &data);}
~WrapA() {
printf("Destroy wrapper! (A %s @ %p)\n", reinterpret_cast<A *>(&data)->valid ? "OK" : "NOT OK", &data);
// Manually call destructor for instance created using placement new
reinterpret_cast<A *>(&data)->~A();
}
void init() {
::new(&data) A();
}
A getA() {
printf("Wrapper returning A %s @ %p\n", reinterpret_cast<A *>(&data)->valid ? "OK" : "NOT OK", &data);
return(*reinterpret_cast<A *>(&data));
}
typename std::aligned_storage<sizeof(A), alignof(A)>::type data;
};
A debug(A data) {
printf("Wrapper returned A %s @ %p\n", data.valid ? "OK" : "NOT OK", &data);
return(data);
}
A test() {
WrapA wrapper;
wrapper.init();
return(debug(wrapper.getA()));
}
int main(void) {
test().bar();
return(0);
}
它打印:
Create wrapper! (A @ 0x7fff1d6a5bde)
Create A @ 0x7fff1d6a5bde
Wrapper returning A OK @ 0x7fff1d6a5bde
Copy A @ 0x7fff1d6a5bdf
From another A OK @ 0x7fff1d6a5bde
Wrapper returned A OK @ 0x7fff1d6a5bdf
Move A @ 0x7fff1d6a5c0f
From another A OK @ 0x7fff1d6a5bdf
Destroy A OK @ 0x7fff1d6a5bdf
Destroy wrapper! (A OK @ 0x7fff1d6a5bde)
Destroy A OK @ 0x7fff1d6a5bde
Hello, World! (A OK @ 0x7fff1d6a5c0f)
Destroy A OK @ 0x7fff1d6a5c0f
输出显示 A 通过了 3 个不同的内存地址,在整个过程中保持有效并且所有拷贝似乎都被正确销毁了。在示例中,test
直接调用了 init
,但在实际情况中,test
使用指向 的指针调用了其他东西wrapper
变量,最终 wrapper.init
在别处被调用,接收大量具有复杂生命周期的参数。
在 WrapA::init
中创建的对象是否安全地传递到 main
并在 WrapA::~WrapA
中适本地处理? A::bar()
被调用时一切正常吗?代码有问题吗?
最佳答案
您可以查看一个管理资源的类,例如 wrapA,您基本上需要问两个问题:
让我们从 1 开始。我发现了一些潜在的问题:
至于 2:
简而言之,wrapA 并非完全错误,因为您可以很好地使用它(如您所演示的)。然而,这也不完全正确。它不满足您期望 c++ 类满足的保证,因此我认为使用 wrapA 很容易编写错误代码。我认为如果您解决有关析构函数和复制构造函数/赋值的问题,使用起来会安全得多。
关于c++ - 放置新的,按值返回并安全地处理临时拷贝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31091223/
我有一个基类和两个派生类,我需要将一个指向派生类对象的指针复制到另一个类中,就像示例一样。 class Base { public: Base(const Base& other); } cl
考虑 Container 类,它主要存储 Box 对象的 unique_ptr vector ,并可以对它们执行一些计算。 class Container { private: std::
引用是指保存的值为对象的地址。在 Python 语言中,一个变量保存的值除了基本类型保存的是值外,其它都是引用,因此对于它们的使用就需要小心一些。下面举个例子: 问题描述:已知一个列表,求生成一个
我正在尝试实现 Bron-Kerbosch 算法,这是一种用于查找派系的递归算法。我设法达到了一个点,它返回了正确数量的派系,但是当我打印它们时,它们不正确 - 添加了额外的节点。我在这里遗漏了什么明
在评估中,我选择了选项LINE I 上的运行时错误。没有未定义行为这样的选项,尽管我认为这是正确的选择。 我不确定,但我认为评估有误。我编译并运行了该程序,它确实打印了 3, 9, 0, 2, 1,
在函数签名中通过 const 值传递参数是否有任何好处(或相反,成本)? 所以: void foo( size_t nValue ) { // ... 对比 void foo( const s
我为 answer to another question 写了一个 OutputIterator .在这里: #include using namespace std; template clas
我有一个由第三方生成的 dll,它具有某种内部数据结构,将其大小限制为 X 个元素。 所以基本上,它有一个以 X 为限制的队列。 据我所知,DLL 是每个进程的,但是是否可以多次加载 DLL?也许每个
假设我有以下两个数据结构: std::vector all_items; std::set bad_items; all_items vector 包含所有已知项和 bad_items vector
如何在不渲染 CGImage 的情况下从另一个 CIImage 复制一个 CIImage 最佳答案 CIImage *copiedImage = [originalImage copy]; 正如您在
我有一个名为 UINode 的 GUI,我想创建一个拷贝并只更改一些内容。该项目由 3 个基本线程组成。 PingThread、RosThread 和 GuiThread。我试图复制粘贴项目文件夹并将
Qt 新手。如果这个问题太幼稚,请多多包涵。在 Windows 操作系统环境中,我有 Qt 对话框框架应用程序,它具有“重复”- 按钮。在同一目录中,有 Qt 应用程序 - (一个带有关闭按钮的对话框
我正在尝试创建一个函数来复制我的卡片结构。我只需复制 cvalue 即可轻松开始。然而,我的 cvalue 没有复制,当应该读取 1000 时它仍然读取 5。 #include #include
string str1("someString"); string str2 = string(str1);//how many copies are made here //copy2 =
我希望了解 boost::bind 执行何种函数对象的内部拷贝。由于这些对象的构造函数似乎没有被调用,我推测这是一种“非常浅的复制”,所以我引入了动态内存分配来产生一些错误。但是,下面代码的运行时输出
我正在查看 http://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#c22-make-default-operations-consis
下面的类方法Augmented3dPoint::getWorldPoint()返回对其成员的引用 cv::Point3f world_point; class Augmented3dPoint { p
我需要通过 MyClass2 将用户定义的 lambda 传递给 MyClass1。我想确保只有一步,没有拷贝。下面的代码实现了吗?有没有更好的方法来做到这一点(比如使用编译器完成的隐式移动)? 注意
在我的数据库访问代码中,我想写一个方法: variant_t GetQueryRows (...) 我想这样调用它: const variant_t result = GetQueryRows (..
我有一个包含引用的类,例如: class A { A(B &b) : b(b) {} // constructor B &b; } 有时b必须是只读的,有时是可写的。当我创建一个 const A
我是一名优秀的程序员,十分优秀!