标签: ownership-semantics

我如何*不*删除析构函数中的成员?

我希望我的类的析构函数删除整个对象,除了其中一个成员,在其他地方删除.首先,这是完全不合理的吗?假设不是,我该怎么做?我认为创建一个带有空体的析构函数会阻止所有成员被删除(因为析构函数不会做任何事情),但似乎并非如此.

c++ destructor ownership-semantics

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

QAction的所有权

将QAction*添加到负责删除QAction*对象的QMenu时?我在QMenu或QAction的文档中找不到它.

void MyClass::contextMenuEvent(QContextMenuEvent *evt)
{
    QMenu menu(this);
    QAction *a = new QAction(tr("Some action"), this);
    menu.addAction(a); // who owns a?
    menu.exec(evt->globalPos());
}
Run Code Online (Sandbox Code Playgroud)

Qt的菜单例如不会删除任何它创建的行动,所以我认为QMenu采取的QAction的所有权.那是对的吗?

qt ownership-semantics qmenu

5
推荐指数
1
解决办法
1840
查看次数

是否有适用于“手柄”的“整体所有权”?

除指针外,句柄具有适当的语义。所以对我来说这样的例子(从零规则中提取):

class module {
public:
    explicit module(std::wstring const& name)
    : handle { ::LoadLibrary(name.c_str()), &::FreeLibrary } {}

    // other module related functions go here

private:
    using module_handle = std::unique_ptr<void, decltype(&::FreeLibrary)>;

    module_handle handle;
};
Run Code Online (Sandbox Code Playgroud)

使用unique_ptr作为用于把手的所有权-在级封装“是一个坏的例子。首先,它利用内部知识,即句柄是指针类型,并使用它使unique_ptr“不透明”句柄类型建立在基本类型上。

句柄可以是任何类型,它们可能是一个指针,它们可能是一个索引或谁知道。最重要的是,您手头上的(例如来自大多数 C API)是一个句柄及其资源释放函数。

是否有适用于句柄语义的适当的“包内所有权” ?我的意思是,已经公开可供使用?

对我来说,unique_ptr等。阿尔。不起作用,我必须对句柄类型什么做出不必要的假设,当我想要的只是通过不透明的句柄类型及其释放功能获得“包中的所有权”时。

通过查看句柄类型内部来构建此信息是没有意义的。这是一个手柄,应该没有关系。

我将在另一个问题的 答案中引用另一个 SO 用户的感受:

创建一个特定的“智能指针”类,不会花很长时间。不要滥用图书馆课程。句柄语义与 C++ 指针的语义完全不同;一方面,取消引用 HANDLE 是没有意义的。

使用自定义智能句柄类的另一个原因 - NULL 并不总是意味着空句柄。有时是 INVALID_HANDLE_VALUE,这是不一样的。

免责声明:

这个问题重新表述并建立在这个问题的基础上:

c++ raii ownership-semantics handle c++11

5
推荐指数
1
解决办法
3534
查看次数

unique_ptr所有权语义

也许我试图过于通用.(下面的原始问题)具体来说,我有Dep一个类的依赖Foo.我也有一个班级MockDep,我正在定义一个班级TestFoo.这是我试图写的构造函数:

TestFoo(unique_ptr<MockDep> dep) : Foo(std::move(dep)), mock_dep_(dep.get()) {}
Run Code Online (Sandbox Code Playgroud)

Foo构造函数看起来像:

Foo(unique_ptr<Dep> dep) : dep_(dep) {}
Run Code Online (Sandbox Code Playgroud)

mock_dep_被指定TestFooMockDep* mock_dep_,并被dep_声明Foounique_ptr<Dep> dep_.我怎样才能mock_dep_包含dep_地址?(由于上述因为std::move(dep)空值而无效dep.)


原帖:

我有一个类型的对象Foo,我将传递给另一个类型的对象OtherObject声称它的所有权,但作为指向其基类的指针.但是,我想抓住一个指向我可以用来引用它的子对象的指针.我写了类似的东西:

Foo(std::unique_ptr<Child> thing) :
    OtherObject(std::move(thing)), child_(thing.get()) {}

OtherObject(std::unique_ptr<Base> thing, ...) { ... }
Run Code Online (Sandbox Code Playgroud)

但是,这似乎不起作用,因为std::move(thing)似乎使从thing.get()后面返回的指针无效.

我可以将Foo参数更改为类型Child*而不是unique_ptr<Child>,但我更愿意能够执行后者,因为它明确记录了所有权语义.

什么是最合适(或失败,不引人注目)的解决方法?

编辑:Foo并且 …

c++ smart-pointers ownership-semantics unique-ptr

5
推荐指数
1
解决办法
296
查看次数

为什么这个函数返回(拥有)值?

代码来自:Genie如何重复一个字符串N次作为字符串数组Genie如何重复一个字符串N次作为一个字符串数组

def repeatwithsep (e: string, n: int, separator: string): string
    var elen = e.length;
    var slen = separator.length;
    var a = new StringBuilder.sized ((elen * n) + (slen * (n - 1)) + 1);
    for var i = 0 to (n - 1)
        if i != 0
            a.append_len (separator, slen)
        a.append_len (e, elen)
    return (owned) a.str
Run Code Online (Sandbox Code Playgroud)

var a是一个局部变量,当一个超出范围时,它将被销毁.为什么这个功能

返回(拥有)a.str

有什么区别

返回a.str

返回(拥有)a.str

(拥有)的好处是什么

memory-management ownership-semantics vala genie

3
推荐指数
1
解决办法
85
查看次数

克隆字符串到特定生命周期

我目前正在尝试在Rust中编写一个小命令行应用程序,并且我已经终生难忘.

extern crate clap;
use self::clap::{App, Arg};
use std::env;

impl<'p> Params<'p> {
    fn get_username_arg<'r>() -> Arg<'r, 'r> {
        let mut arg = Arg::with_name("Username")
            .short("u")
            .long("username")
            .takes_value(true);
        match env::var("USERNAME") {
            Ok(username) => {
                // How do I pass `username` to default_value?
                arg.default_value(username)
            }
            Err(e) => arg.required(true),
        }
    }
    // More code below...
}
Run Code Online (Sandbox Code Playgroud)

问题是我正在尝试传递username默认值方法,该方法需要str具有生命周期的方法'r.我尝试克隆,但我无法弄清楚如何告诉它克隆的生命周期是什么.我尝试了以下几点:

let cln = (&*username).clone::<'r>();
arg.default_value(username)
Run Code Online (Sandbox Code Playgroud)

出于某种原因,它现在告诉我,username活得不够长,即使自从克隆数据以来它也无关紧要.

所以我的问题是,如何进行编译?

编辑:我想补充一点,对我来说重要的是签名与生命周期参数保持一致.我不介意做一些昂贵的操作,比如克隆来完成这项工作.

ownership-semantics rust

3
推荐指数
1
解决办法
1347
查看次数

移动后改变结构的字段

我对以下行为感到困惑:有人可以解释发生了什么吗?

考虑代码:

struct Point {
    cx : u32,
}
fn main() {
    let mut p1 = Point { cx: 100 };
    let     p2 = p1; 
    p1.cx      = 5000;
    // println!("p1.x = {}", p1.cx); // disallowed as p1.cx is "moved" ... ok
    println!("p2.x = {}", p2.cx); // ==> prints 100 (!)
}
Run Code Online (Sandbox Code Playgroud)

具体来说,我感到困惑的是:

  1. 更新p1.cx允许即使举动已经发生,
  2. 返回的值p2.x实际上不是更新后的 5000,而是旧的100.

我期待新值,因为没有复制特征(因此移动),所以期待只有一个单元格,其更新值 ( 5000) 应该被打印出来。

但是,我一定错过了一些东西。有小费吗?提前致谢!

alias move ownership-semantics rust

3
推荐指数
1
解决办法
208
查看次数

Rust 可以使用传递给函数的迭代器吗?

我正在尝试用 Rust 实现一个简单的 REPL 计算器,但我到处碰壁。

我在迭代硬编码字符串时消耗字符。当我点击数字字符时,我想将控制权传递给一个函数,该函数将消耗该数字的其余部分(假设该数字有多于一位数字)并返回该数字,并将其转换为整数。

Chars我在将迭代器传递给函数时遇到问题。我收到的错误是use of moved value: 'iter'.

我知道我不能改变我给别人的东西 - 其所有权已移动的东西 - 但我不知道有任何其他方法可以做到这一点,特别是因为 Chars 迭代器是不可复制的。

#[derive(Clone, Debug)]
enum Token {
    Addition,
    Substraction,
    Multiplication,
    Division,
    Integer(i32),
    Error,
}

fn consume_number(mut iter: std::str::Chars) -> Option<i32> {
    while let Some(item) = iter.next() {
        println!("{:?}", item);
    }

    return Some(1337);
}

fn tokenize(line: &str) -> Vec<Token> {
    let mut iter = line.chars();
    let mut tokens = Vec::new();
    let mut token;

    while let Some(c) = iter.next() {
        if c.is_whitespace() { …
Run Code Online (Sandbox Code Playgroud)

iterator ownership-semantics move-semantics rust

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

Rust集合是否有能力拥有他们存储的数据?

给出以下代码(不编译):

fn main() {
    let mut v = vec!();

    {
        let name = "Bob the Builder".to_string();

        v.push(&name);
    }

    for m in &v{
        println!("{}", m);
    }
}
Run Code Online (Sandbox Code Playgroud)

我创建了一个绑定到Rust String类型的变量,它将超出第一组花括号中的范围.有没有办法以某种方式移动String的所有权,使得向量本身拥有它?

这是一个任意的例子,但我只是想了解这个概念是否可行.

我已经知道,如果我使用字符串文字,这将被视为一个静态字符串,它将在整个应用程序的生命周期中存在,因此这段代码将编译但我只是想了解Rust中的集合是否可以拥有数据.我知道Rust不是Objective-C,但Objective-C的集合能够保留他们的数据.

ownership-semantics rust

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

为什么Rust书籍在复制顶级结构时会将变量分配给另一个?

Rust编程语言的所有权部分中,Strings表示为具有3个字段的结构(3个字段中的一个是指向实际字节向量的指针).有一个例子:

let s1 = String::from("hello");
let s2 = s1;
Run Code Online (Sandbox Code Playgroud)

这本书解释此作为复制包含在3场结构s1s2(但不是字节矢量),然后标记包含在所述结构s1为"无效"(图4-4).

为什么它以这种方式呈现而不是呈现s2为指向相同的顶级结构s1,然后标记s1为"无效"?

这种替代演示会导致语义上的明显差异(或者甚至会导致问题)吗?如果没有,是因为它更好地反映了底层实施吗?如果是这样,为什么实现会进行这样的复制操作?

ownership-semantics rust

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