- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我的问题(将在这之后提出,抱歉介绍太长,问题在粗体中)最初是受 Herb Sutters Exceptional C++ 我们在哪里找到这样的东西:
<截图>
...
int main()
{
GenericTableAlgorithm a( "Customer", MyWorker() );
a.Process();
}
with
class GenericTableAlgorithm
{
public:
GenericTableAlgorithm( const string& table,
GTAClient& worker );
bool Process();
private:
struct GenericTableAlgorithmImpl* pimpl_; //implementation
};
class GTAClient
{
///...
virtual bool ProcessRow( const PrimaryKey& ) =0;
//...
};
class MyWorker : public GTAClient
{
// ... override Filter() and ProcessRow() to
// implement a specific operation ...
};
</snip>
Now, I have the following problems with that code (and no, I in no way doubt Mr. Sutter's prowess as a C++ expert):
MyWorker
used in the NVI of GenericTableAlgorithm
accessed by GTAClient
(polymorphic) interface; this rules out that the implementation owns a (value)member of type GTAClient
, since that would cause slicing etc. value-semantics don't mix well with polymorphism.MyWorker
either since that class is unknown to GenericTableAlgorithm
.MyWorker()
) are rarely a good idea, i assume the author's plan was to use the extended life-time of temporaries bound to (const) references, and store such a reference in the object pimpl_
points to and use it from there. (Note: there is also no clone-member function in GTAClient, which could have made this work; let's not assume there is a RTTI-typeinfo-based Factory lurking in the background.)
The standard in §12.2.5(the C++0x version but it's the same in C++, don't know about the chapter number) makes the following exception from lifetime extension:"-A temporary bound to a reference member in a constructor’s ctor-initializer (12.6.2) persists until the constructor exits."
Therefore the object cannot be used in the call of the client code a.Process(); because the referenced temporary from MyWorker()
is already dead!
Consider now an example of my own crafting that demonstrates the problem (tested on GCC4.2):
#include <iostream>
using std::cout;
using std::endl;
struct oogie {
~oogie()
{
cout << "~oogie():" << this << ":" << m_i << endl;
}
oogie(int i_)
: m_i(i_)
{
cout << "oogie():" << this << ":" << m_i << endl;
}
void call() const
{
cout << "call(): " << this << ":" << m_i << endl;
}
int m_i;
};
oogie func(int i_=100)
{
return oogie(i_);
}
struct kangoo
{
kangoo(const oogie& o_)
: m_o(o_)
{
}
const oogie& m_o;
};
int main(int c_, char ** v_)
{
//works as intended
const oogie& ref = func(400);
//kablewy machine
kangoo s(func(1000));
cout << ref.m_i << endl;
//kangoo's referenced oogie is already gone
cout << s.m_o.m_i << endl;
//OK, ref still alive
ref.call();
//call on invalid object
s.m_o.call();
return 0;
}
产生输出
oogie():0x7fff5fbff780:400oogie():0x7fff5fbff770:1000~oogie():0x7fff5fbff770:10004001000call(): 0x7fff5fbff780:400call(): 0x7fff5fbff770:1000~oogie():0x7fff5fbff780:400
您可以看到,在 const oogie& ref 的情况下,func() 的立即绑定(bind)到引用的临时返回值具有延长的所述引用的生命周期(直到 main 结束),所以没关系。
但是:1000-oogie 对象在 kangoo-s 构造完成后就已经被销毁了。代码有效,但我们在这里处理的是一个不死物体......
所以再次提出问题:
首先,我是否遗漏了什么代码是否正确/合法?。
其次,为什么 GCC 没有给我警告,即使指定了 -Wall?应该吗?可以吗?
谢谢你的时间,
马丁
最佳答案
我认为这是一个不太清楚的棘手部分。几天前有一个类似的问题。
默认情况下,当创建它们的完整表达式完成时,临时对象以相反的构造顺序被销毁。到目前为止,一切都很好并且可以理解,但随后出现异常 (12.2 [class.temporary]/4,5),事情变得困惑。
我将从工程/编译器的角度处理问题,而不是处理标准中的确切措辞和定义。临时对象在堆栈中创建,当函数完成时,堆栈帧被释放(堆栈指针移回函数调用开始前的原始位置)。
这意味着临时对象永远无法在创建它的函数中存活下来。更确切地说,它无法在定义它的范围内存活,即使它实际上可以在创建它的完整表达式 内存活。
标准中的所有异常(exception)都不受此限制,在所有情况下,临时文件的生命周期都会延长到保证不超过创建临时文件的函数调用的时间点。
关于c++ - 这个 C++ 临时绑定(bind)到引用成员应该是非法的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1477028/
我不知道该怎么做... function f1() { var x = 10; function f2(fx) { var x; x = 6;
早期绑定(bind)和后期绑定(bind)有什么区别? 最佳答案 简短的回答是,早期(或静态)绑定(bind)是指编译时绑定(bind),后期(或动态)绑定(bind)是指运行时绑定(bind)(例如
如何在 SwiftUI View 上使用 Binding(get: { }, set: { }) 自定义绑定(bind)与 @Binding 属性。我已成功使用此自定义绑定(bind)与 @State
我经常发现自己遇到问题,即控件的两个(相关)值被更新,并且两者都会触发昂贵的操作,或者控件可能会暂时处于不一致的状态。 例如,考虑一个数据绑定(bind),其中两个值 (x,y) 相互减去,最终结果用
我想通过我的 ViewModel 控制我的一个窗口的高度和宽度。 这看起来很简单。 但没有。它不起作用。 它检查 ViewModel 的 Width但不是 Height . 奇怪的是,如果我切换 W
UI5中一次性绑定(bind)和单向绑定(bind)有什么区别? 是否有任何用户特定的用例我会使用它们? 我无法从文档中获得太多信息。 最佳答案 单程 它的作用:单向数据流。模型数据的变化(例如通过
(define make (lambda (x) (lambda (y) (cons x (list y))))) (let ((x 7) (p (make 4))) (cons
尽管我或多或少地了解什么是语言绑定(bind),但我很难理解它们是如何工作的。 例如,谁能解释一下如何为 WinAPI 制作 Java 绑定(bind)? 最佳答案 如果您搜索 Foreign Fun
谁能解释为什么我可以重新绑定(bind)列表但不能+? (binding [list vector] (list 1 3)) (binding [list +] (list 1 3)) (bi
我真的很喜欢 Caliburn 和命名约定绑定(bind),我很惊讶 可见性与“CanNAME”约定用于保护 Action 的方式不同。 据我所知, BooleanToVisibilityConver
我了解动态绑定(bind)的实现方式以及静态绑定(bind)和动态绑定(bind)之间的区别,但我只是无法理解动态绑定(bind)的定义。基本上它是一种运行时绑定(bind)类型。 最佳答案 基本上,
http://jsfiddle.net/3NRsd/ var foo = $("div").bind("click", function() { $("div").animate({"hei
这个问题我快疯了...我有一个用户控件,它有一个用于插入操作的 FormView 和一个用于所有其他操作的 GridView。 在这两个控件中,我都有一个 DropDownList,如下所示: '
我有一个绑定(bind)到 ListBox 的地址的 ObservableCollection。然后在 ItemTemplate 中,我使用 {Binding .} 绑定(bind)到当前地址记录。这
如果我有以下简单的 js/knockout 代码: .js( View 模型): var image = ko.observable('http://placehold.it/300x150'); 看
我正在 aurelia 上开发一个自定义属性,让用户在输入文本区域时从列表中进行选择。例如,用法将是这样的: 正如您可能注意到的,auto-complete是属性。现在,当我想显示提示时,我想在自定
我正在使用 EventEmitter2作为我的应用程序内部的消息总线。现在我需要绑定(bind)和取消绑定(bind)一些事件处理程序。因为我也希望他们bind将它们添加到给定的上下文中,我最终得到以
我有以下函数调用: $(".selector").on("click", callback.bind(this, param1, param2)); 在我的回调函数中,我想使用绑定(bind)的 th
我目前正在试验新的编译绑定(bind),并且(再次)达到了我在拼图中遗漏了一个小问题:为什么我必须调用 Bindings.Update?直到现在,我还认为实现 INotifyPropertyChang
我正在阅读一本关于编写 JavaScript 框架的书,并找到了这段代码。但是我不明白它是如何工作的,尤其是 bind.bind 的用法?有人知道吗? var bind = Function.prot
我是一名优秀的程序员,十分优秀!