标签: object-lifetime

为什么我不能在多重继承期间"侧向"动态广播?

以下代码抛出std :: bad_cast

struct Foo {
    void foo () {}
};

struct Bar {
    Bar () {
        dynamic_cast <Foo &> (*this) .foo ();
    }
    virtual ~ Bar () {}
};

struct Baz : public Foo, public Bar {
};

int main ()
{
    Baz b;
}
Run Code Online (Sandbox Code Playgroud)

我记得曾经读过dynamic_cast如何进行实现性能权衡,因为"它遍历了完整的继承格"以便正确评估.编译器在这里需要做的是先强制然后再次向下.

可以进行上述工作还是需要添加 virtual Foo* Bar::as_foo()=0;

c++ inheritance constructor dynamic-cast object-lifetime

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

参考参数寿命

鉴于以下内容:

class ParamClass {...};

class MyObject {
public:
    void myMethod(ParamClass const& param) { _myPrivate = param; }

private:
    ParamClass _myPrivate;
}

[...]

MyObject obj;

void some_function(void)
{
    ParamClass p(...);
    obj.myMethod(p);
}
Run Code Online (Sandbox Code Playgroud)

在对象p的生命周期结束时_myPrivate会发生什么?编辑:我仍然可以使用_myPrivate访问对象p的副本吗?

谢谢!

c++ object-lifetime

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

在 C++ 中链接调用临时变量

我有一个对字符串进行转换的类,如下所示

class transer{
    transer * parent;
protected:
    virtual string inner(const string & s) = 0;
public:
    string trans(const string & s) {
        if (parent) 
            return parent->trans(inner(s));
        else 
            return inner(s);
    }
    transer(transer * p) : parent(p) {}

    template <class T>
    T create() { return T(this); }
    template <class T, class A1>   // no variadic templates for me
    T create(A1 && a1) { return T(this, std::forward(a1)); }
};
Run Code Online (Sandbox Code Playgroud)

所以我可以创建一个子类

class add_count : public transer{
    int count;
    add_count& operator=(const add_count &);
protected:
    virtual …
Run Code Online (Sandbox Code Playgroud)

c++ templates object-lifetime rvalue-reference temporaries

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

单线程C++函数调用中的undebuggable非确定性heisenbug

我在这里结束了:我有一个单线程的C++程序.这里有一些经验数据和背景信息,我试图突出最重要的关键词;

  • 我正在谈论的整个部分没有任何系统调用,除了标准C++库可能执行的内存(de-)分配调用(std::set涉及到).这是一个纯粹的逻辑算法.
  • 这种行为应该是确定性的,取决于输入,我不会改变.
  • 如果错误表现出来,那么程序就会陷入无限循环,它似乎开始分配超出任何界限的内存.
  • 该bug并没有表现出来预见的,我可以在命令行中运行的程序,有时(可能是30%-50%)的错误表现,否则,一切顺利,运行正常,据我可以告诉.
  • 一旦我不直接从提示符运行程序,但在gdb或valgrind中,错误消失了,程序永远不会死.
  • 现在是最好的部分:我将问题追溯到(模板化的)非虚拟成员函数调用.就在呼叫之前,我打印一个消息std::cout,这我可以看到在终端.所述第一线在函数内部也有一个调试消息,这是从未示出.

我再也看不到任何合理的解释了.也许你可以想出如何继续下去.


编辑:重要的代码行,我更改了行号,以便我们可以参考它们并省略不相关的部分,所以并非所有内容似乎都是最有意义的.

a.cpp

 10     std::set<Array const*>* symbols;
 11     std::set<Array const*> allSymbols;
 12     symbols = &allSymbols;
 //  ... allSymbols are populated with std::inserter
 15     std::cout << "eval; cd = " << &cd << ", cg = " << &cd.cg << std::endl;
 16 …
Run Code Online (Sandbox Code Playgroud)

c++ debugging object-lifetime non-deterministic heap-corruption

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

返回传递对象的引用

我知道我们不能通过引用返回一个局部变量,因为它会超出范围.虽然我在返回传递的引用时有点困惑.例如,以下示例是合法的还是会导致未定义的行为?

classobject &function(classobject &obj) {
 return obj;
}
Run Code Online (Sandbox Code Playgroud)

c++ scope pass-by-reference object-lifetime

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

如何将某些堆内存的所有权转移出函数?

我正在尝试编写一个函数,将命令行实用程序 (image-magick) 的标准输出加载到结构的成员中。我认为由于图像可能是 MB,我最好尽可能避免复制。

/// An image data container used internally.
/// Images are 8-bit single channel for now.
pub struct Image<'a> {
    /// Width of the image in pixels.
    pub width: u32,
    /// Height of the image in pixels.
    pub height: u32,
    /// The buffer containing the image data, as a slice.
    pub pixels: &'a [u8],
}

// Load a file by first using imageMagick to convert it to a .pgm file.
fn load_using_magick<'a>(path: Path) -> Image<'a> {
    use …
Run Code Online (Sandbox Code Playgroud)

struct memory-management object-lifetime rust

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

防止早期物体破坏

在C++中,如果我写的话

token make_token() { return token{}; }
Run Code Online (Sandbox Code Playgroud)

然后按如下方式使用它

void use_token()
{
  make_token();
  // extra code
}
Run Code Online (Sandbox Code Playgroud)

在没有为变量赋值的情况下,token析构函数会在执行额外代码之前触发.如何让析构函数只在函数结束时触发而不必创建变量?

注意:我想完全避免变量.我知道我可以做auto& t = make_token()或类似,但我想通过返回没有立即触发析构函数的东西(我不知道是什么)来避免这种情况.

为什么我想要这个:基本上,在我的应用程序(编程语言的编译器)中,我将这些东西称为令牌.令牌的构造函数可以放置一个{和缩进,然后它的析构函数可以放入}和取消缩进.我认为设置按值返回这些标记的函数是个好主意,但我实际上并不想将它们分配给任何值,因为标记是无用的并且没有函数.

为了减轻混乱,我token不是一个词法标记.我用这项工作token代替工作cookie.它意味着在构造函数中执行某些操作,等到其作用域结束,然后在其析构函数中执行某些操作.而已.顺便说一句,如果我用C#写这个,我会写类似的东西

 using (make_token())
 {
   // my code here
 }
Run Code Online (Sandbox Code Playgroud)

它会按预期工作.但事实证明,在C++中,这么简单的事情很难实现.

c++ variables destructor object-lifetime

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

具有空初始化的对象的生命周期

目前的标准草案在[basic.life/1]中说(以前的标准有相似的措辞):

对象或引用的生命周期是对象或引用的运行时属性.如果一个对象属于类或聚合类型,并且它或其子对象之一由除了普通默认构造函数之外的构造函数初始化,则称该对象具有非空的初始化.[注意:通过简单的复制/移动构造函数进行初始化是非空的初始化. - 结束注释]类型T对象的生命周期从以下开始:

(1.1)获得具有适当对齐和T型尺寸的存储,并且

(1.2)如果对象具有非空的初始化,则其初始化完成,

看到这段代码:

alignas(int) char obj[sizeof(int)];
Run Code Online (Sandbox Code Playgroud)

basic.life/1是否意味着这里int(和其他几种类型,具有相同或更小的对齐/尺寸要求int)已经开始了它的生命周期?

这甚至意味着什么?如果一个对象已经开始它的生命周期,它是否被创建?[intro.object/1]说:

[...]通过定义([basic.def]),通过new-expression,隐式更改union的活动成员([class.union])或创建临时对象时创建对象([conv.rval],[class.temporary])[...]

因此,根据这一点,我obj(作为int)不是创建的.但它作为一个int(以及其他可能是无限类型的空间可初始化对象)的生命已经开始.

我很困惑,你能澄清一下吗?

c++ object-lifetime language-lawyer c++17

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


访问用户定义的析构函数已启动但未完成的对象真的是UB吗?

这个问题是由于Reddit的讨论引起的,一位用户告诉我,引用了标准关于对象生命周期的规则:

我很确定在技术上访问一个对象是 UB,而它正在被破坏。

例如,我依赖于管理后台线程的类;我让他们的析构函数通知线程退出并等待它退出,并且该线程可以访问该对象。我需要重构我的代码吗?

c++ object-lifetime

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