对象的构造会分配该对象生命周期所需的数据,但还会创建另一个需要保留对数据的引用的对象:
pub fn new() -> Obj {
let data = compute();
Obj {
original: data,
processed: AnotherObj {
reference: &data
}
}
}
Run Code Online (Sandbox Code Playgroud)
是否可以用Rust的术语表达这一点?
在这里,我想要Obj,AnotherObj并且data拥有相同的生命周期,当然还没有new()通话。
这是最近出现的事情,我觉得它显然不应该起作用:
#include <iostream>
#include <memory>
int main()
{
std::shared_ptr<int>& ptr = const_cast<std::shared_ptr<int>&>(
static_cast<const std::shared_ptr<int>&>(
std::shared_ptr<int>(
new int(5), [](int* p) {std::cout << "Deleting!"; *p = 999; delete(p); }
)
)
);
std::cout << "I'm using a non-const ref to a temp! " << *ptr << " ";
}
Run Code Online (Sandbox Code Playgroud)
shared_ptr此处不需要使用,但自定义删除器允许轻松演示结果对象的生命周期。Visual Studio、Clang 和 GCC 的结果输出是相同的:
我正在使用非常量引用来表示临时值!5 删除!
这意味着结果的生命周期shared_ptr已通过某种机制扩展到匹配std::shared_ptr<int>& ptr.
现在,我知道在常量引用的情况下,临时对象的生命周期将扩展到引用的生命周期。但是唯一的命名对象是非常量引用,我希望所有其他中间表示的生命周期仅等于初始化表达式。
此外,Microsoft 有一个扩展,它允许非常量引用延长绑定临时的生命周期,但即使禁用该扩展,这种行为似乎也存在,此外,也出现在 Clang 和 GCC 中。
根据这个答案,我相信临时对象被隐式创建为const,因此尝试修改引用的对象ptr可能是未定义的行为,但我不确定这些知识是否告诉我有关为什么延长生命周期的任何信息。我的理解是,这是修改UB 的 const的行为,而不是简单地对它进行非常量引用。 …
一些类型被标准定义为隐式生命周期类型,数组就在其中。一些函数隐式地创建具有隐式生命周期的对象(malloc 等就在其中),这里有一个隐式创建具有隐式生命周期的对象的操作列表。https://en.cppreference.com/w/cpp/language/object(我希望这是正确的,但对这个问题的其余部分我们假设new作品malloc在这种情况下隐含的对象创建的目的)。
如果数组不创建其元素,则隐式创建数组意味着什么?是不是意味着
T* implicit_array = reinterpret_cast<T*>(::operator new(sizeof(T) * count, std::align_val_t{alignof(T)}) );
Run Code Online (Sandbox Code Playgroud)
产生适用于指针算术的implicit_array 对象,即为稍后使用placement new 构造的类型T 的元素提供有效的存储?
这是否意味着这new (implicit_array + i) T{...}是一个定义明确的操作,即使按照标准,implicit_array + i不一定定义?https://eel.is/c++draft/expr.unary#op-3.2。
或者这意味着
std::byte* memory =
reinterpret_cast<std::byte*>(::operator new(sizeof(T) * capacity, std::align_val_t{alignof(T)}));
new (memory) T{args1 ...}
// build more objects
new (memory + (k-1)*sizeof(T) ) T{args_k ...}
T* implicit_array = std::launder(reinterpret_cast<T*>(memory) ); // does it produce array of k elements?
Run Code Online (Sandbox Code Playgroud)
将其implicit_array视为具有 …
为什么using变量被视为只读?它是c#语言规范还是托管语言规范?这是因为c#是.net语言?提前致谢.
注意:using变量是在using语句中出现的变量
示例代码:
using (Form s = new Form)
{
myfunc(ref s);
}
Run Code Online (Sandbox Code Playgroud)
我们无法在使用块中更改using变量的值.代码会引发错误.
注意:我不想让你讨论readonly关键字.
假设我有这样一个类:
class A
{
public:
A(){}
~A(){}
};
Run Code Online (Sandbox Code Playgroud)
并通过Luabind将它暴露给Lua,如下所示:
module(luaState)
[
class_<A>("Foo")
.def(constructor<>())
];
Run Code Online (Sandbox Code Playgroud)
最后在这样的脚本中实例化它:
A = Foo();
Run Code Online (Sandbox Code Playgroud)
那时A的实际"存在状态"是什么?
它是在堆中的某个地方,并且lua在某处保留了对它的引用?(或luabind ::对象?)
我觉得它只能是一个指针,如新的或同等的.
但是,我可以将函数绑定到接受引用的lua,例如lua_doSomething(A & a),最终会有一个实际的引用.诚然,我知道这很可能只是路过被luabind a的*a,但我不知道如果这是怎么回事了.
我问这个的原因是为了更好地理解和预测在脚本中实例化的对象的生命周期.
那个,我不确定所有权或生命周期是否会改变,如果不是像上面那样将类暴露给lua,我这样做:
A * lua_CreateA()
{
return new A();
}
module(luaState)
[
class_<A>("Foo")
];
module(luaState)
[
def("createA",&lua_CreateA)
];
Run Code Online (Sandbox Code Playgroud)
并使用它像
A = createA();
Run Code Online (Sandbox Code Playgroud)
根据我到目前为止所理解的逻辑,这个案例需要我进行清理,因为我是分配一个新对象的人,除非为luabind这样的赋值与使用绑定构造函数这样做.
简而言之,我真的很困惑对象的生命周期和这里的东西...我搜索与此相关的关键字,但我只是得到像http://www.gamedev.net/topic/525692-luabind这样的东西 -ownership和-破坏/
这不是我想知道的.我想了解在幕后处理有关分配,实例化,生命周期和所有这些事情的具体方法.
在D中,可以使用scope,即,在堆栈上分配类
void foo()
{
scope example = new Bar();
}
Run Code Online (Sandbox Code Playgroud)
现在,如果类Foo具有类Bar作为成员,是否有任何方法可以Bar在内部存储Foo并使用Foola C++进行拆分?
我曾希望如此
import std.stdio;
class Foo {
this() { writeln("Foo"); }
~this() { writeln("~Foo"); }
scope Bar inside;
}
class Bar {
this() { writeln("Bar"); }
~this() { writeln("~Bar"); }
};
void main()
{
scope f = new Foo();
writeln("I'm a main!");
}
Run Code Online (Sandbox Code Playgroud)
会产生类似的东西
Bar
Foo
我是主角!
~Bar
~Foo
相反,我只能得到
Foo
我是主力!
〜富
看起来将类成员存储为垃圾收集引用而不是就地存储只是不必要地使堆布局复杂化而没有什么好处.什么是scope做在这种情况下,如果不指定举行Bar …
假设我有三个对象:'a','b'和'c'.对象'a'和'c'是长寿的,静态引用的服务单例.对象'b'是短暂的,即没有静态引用使其保持活动状态.
现在假设对象'a'在其一个方法的范围内创建对象'b'的实例,例如
B b = new B();
Run Code Online (Sandbox Code Playgroud)
进一步假设B类看起来像这样:
public B ()
{
C.ActionList.Add ( SomeMethod );
}
void SomeMethod ()
{
...
}
Run Code Online (Sandbox Code Playgroud)
现在,对象'b'存活了多长时间?我的推测是,它超出了称为构造函数的方法的范围; 具体来说,只要它的方法仍然在对象'c'的'ActionList'中.
那是对的吗?如果没有,它会被垃圾收集,当'c'运行'ActionList'中的所有方法时会发生什么?
额外的问题:如果'b'上的方法没有被命名,但匿名并在构造函数中写入如下,该怎么办?
public B ()
{
C.ActionList.Add ( () => {
...
} );
}
Run Code Online (Sandbox Code Playgroud) 我一直想知道,C++中的字符串常量有多长.例如,如果我在函数内部创建了一些const char*str ="something",那么返回str的值是否安全?
我写了一个示例程序,看到这样的返回值仍然存储了该字符串,我感到非常惊讶.这是代码:
#include <iostream>
using namespace std;
const char *func1()
{
const char *c = "I am a string too";
return c;
}
void func2(const char *c = "I'm a default string")
{
cout << c << endl;
}
const int *func3()
{
const int &b = 10;
return &b;
}
int main()
{
const char *c = "I'm a string";
cout << c << endl;
cout << func1() << endl;
func2();
func2("I'm not a default string");
cout …Run Code Online (Sandbox Code Playgroud) 我遇到过这样一种情况,即能够将方法调用链接到临时变量会非常有用:
draw(Quad(0, 0, 1, 1).rotate(90)); // <-- .rotate() returns a Quad reference
struct Quad{
Quad(float x, float y, float width, float height){...}
Quad & rotate(float degrees){
...
return *this;
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我不确定临时变量是否会保持活动足够长时间以使draw()函数使用它.这样做安全吗?
在xamarin应用程序中,有关使用autofac的lifescopescope以及何时使用它们的初学者问题。
如本文所述(https://nblumhardt.com/2011/01/an-autofac-lifetime-primer/),autofac文档(http://docs.autofac.org/en/latest/ (lifetime /),他们在不从根容器中解决问题,而是使用单独的lifescope并根据工作单位进行思考的过程中付出了很多努力,因为autofac保留了对一次性对象的引用,即使它们不再使用,直到它们被创建的范围都被废弃为止,因此存在内存泄漏的危险。
但是,在开发Xamarin应用程序并查找示例时,我找不到这种用法的示例,也没有想到将IoC容器用作服务定位器anitpattern,何时使用?(https://xamarinforms.wordpress.com/tag/dependency-injection/)
这些文章展示了一个“最佳实践”示例,该示例在xamarin应用程序中设置导航并解析必要的视图模型,并将其设置为与页面的绑定上下文:https : //developer.xamarin.com/guides/xamarin-forms/enterprise-application- pattern / navigation /和https://developer.xamarin.com/guides/xamarin-forms/enterprise-application-patterns/mvvm/#automatically_creating_a_view_model_with_a_view_model_locator 不知道这是xamarin形式的最佳实践还是最佳方法。
但是,当这些视图模型由autofac实例化并且这些模型之一依赖于可抛弃的类时,会发生什么呢?
当请求viewModel时,将解析一个与页面匹配的新实例,并将其放在导航堆栈中。因此,在浏览页面时,堆栈变得越来越大,autofac会保留对所有一次性对象的引用,并且在应用程序的生命周期中(所有内容都可以从主容器中解析出来,没有使用单独的作用域)可能会持续很长时间。这里有遇到内存问题的风险吗?如果仍然存在引用这些未使用对象的风险,何时将所有这些未使用对象收集为垃圾?可能我对这实际上是如何工作缺少某种理解,或者在用法上犯了一个错误,但请注意https://developer.xamarin.com/guides/xamarin-forms/enterprise-application-patterns/navigation/中的InternalNavigateToAsync方法 只是导航到另一个页面时将页面添加到堆栈中。
PS。在侧面说明,这看起来不错(scope.Resolve):
using(var scope = container.BeginLifetimeScope())
{
for(var i = 0; i < 100; i++)
{
var w = scope.Resolve<Worker>();
w.DoWork();
}
}
Run Code Online (Sandbox Code Playgroud)
并且来自(http://docs.autofac.org/en/latest/register/registration.html和其他一些地方。):
using(var scope = container.BeginLifetimeScope())
{
var reader = container.Resolve<IConfigReader>();
}
Run Code Online (Sandbox Code Playgroud)
是在autofac文档中使用的,我想这最后一个是错字了吗?(container.Resolve而不是scope.Reslove,它周围有一个useless(?)范围块,无论如何在这个范围块内从主容器中解析...