标签: object-lifetime

为可变范围目的使用大括号是错误的吗?

我有时会使用大括号来隔离代码块,以避免以后错误地使用变量.例如,当我SqlCommand在同一个方法中放入几个s时,我经常复制粘贴代码块,最后混合名称并执行两次命令.添加大括号有助于避免这种情况,因为SqlCommand在错误的位置使用错误将导致错误.这是一个例子:

Collection<string> existingCategories = new Collection<string>();

// Here a beginning of a block
{
    SqlCommand getCategories = new SqlCommand("select Title from Movie.Category where SourceId = @sourceId", sqlConnection, sqlTransaction);
    getCategories.Parameters.AddWithValue("@sourceId", sourceId);
    using (SqlDataReader categoriesReader = getCategories.ExecuteReader(System.Data.CommandBehavior.SingleResult))
    {
        while (categoriesReader.Read())
        {
            existingCategories.Add(categoriesReader["Title"].ToString());
        }
    }
}

if (!existingCategories.Contains(newCategory))
{
    SqlCommand addCategory = new SqlCommand("insert into Movie.Category (SourceId, Title) values (@sourceId, @title)", sqlConnection, sqlTransaction);

    // Now try to make a mistake and write/copy-paste getCategories instead of addCategory. It will not …
Run Code Online (Sandbox Code Playgroud)

c# scope coding-style stylecop object-lifetime

19
推荐指数
4
解决办法
2404
查看次数

C#Thread对象的生命周期

假设我有如下代码:

int Main()
{
    if (true)
    {
       new Thread(()=>
          {
              doSomeLengthyOperation();
          }).Start();
    }
    while (true)
    {
       //do nothing
    }
}
Run Code Online (Sandbox Code Playgroud)

有2个线程,我会打电话给主线程正在执行main()函数的线程,该线程被new'ed了里面的"如果"测试为主题A.

我的问题是,线程A什么时候被销毁?do doSomeLenghtyOperation()能够完成吗?

由于没有指向线程A的引用,它是否会被标记为垃圾收集的候选者:

  1. 紧接着"new Thread().Start()"语句本身完成了吗?
  2. 退出"if(true)"范围后立即?
  3. doSomeLengthOperation()运行完成后?
  4. 决不?

我看到的所有示例都是Main()持有引用,然后主线程在退出之前等待与线程A连接.我很好奇上面代码的生命周期是什么.

提前致谢!

c# multithreading object-lifetime

18
推荐指数
3
解决办法
8297
查看次数

在C函数中创建的对象的存在

已经建立(见下文)new创建对象需要放置

int* p = (int*)malloc(sizeof(int));
*p = 42;  // illegal, there isn't an int
Run Code Online (Sandbox Code Playgroud)

然而,这是在C中创建对象的一种非常标准的方式.

问题是,int如果是在C中创建并返回到C++ ,是否存在?

换句话说,以下是否保证合法?假设intC和C++是相同的.

foo.h中

#ifdef __cplusplus
extern "C" {
#endif

int* foo(void);

#ifdef __cplusplus
}
#endif
Run Code Online (Sandbox Code Playgroud)

foo.c的

#include "foo.h"
#include <stdlib.h>

int* foo(void) {
    return malloc(sizeof(int));
}
Run Code Online (Sandbox Code Playgroud)

main.cpp中

#include "foo.h"
#include<cstdlib>

int main() {
    int* p = foo();
    *p = 42;
    std::free(p);
}
Run Code Online (Sandbox Code Playgroud)

有关安置强制性质的讨论的链接new:

c c++ object-lifetime language-lawyer

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

破坏功能参数的顺序是什么?

这是对我之前问题的后续跟踪功能参数的破坏顺序是什么?因为我不小心把参数与参数混淆了 感谢Columbo和TC在该问题的评论中清除术语混淆.

如果某些函数的主体f带有参数p_1,...,p_n类型T_1,......,T_n分别抛出异常,完成或返回,参数被破坏的顺序是什么?为什么?如果可能,请提供标准参考.

例子:

template <typename ... Args>
void f(Args ... params) {} // in what order are params destroyed?

void f(T1 p1, T2 p2, T3 p3) {} // in what order are p1, p2 and p3 destroyed?
Run Code Online (Sandbox Code Playgroud)

c++ parameters function object-lifetime language-lawyer

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

关于智能指针的一个问题及其必然的非决定论

在过去的两年里,我一直在我的项目中广泛使用智能指针(boost :: shared_ptr).我理解并欣赏他们的好处,我一般都喜欢他们.但是我越是使用它们,我就越想念C++的确定性行为,关于内存管理和RAII,我似乎更喜欢编程语言.智能指针简化了内存管理的过程并提供了自动垃圾收集等功能,但问题是一般使用自动垃圾收集和智能指针特别引入了(de)初始化顺序的某种程度的不确定性.这种不确定性使控制权远离程序员,并且正如我最近意识到的那样,它完成了设计和开发API的工作,

为了详细说明,我目前正在开发一个API.此API的某些部分要求在其他对象之前初始化或销毁某些对象.换句话说,(de)初始化的顺序有时很重要.举个简单的例子,假设我们有一个名为System的类.系统提供一些基本功能(在我们的示例中记录)并通过智能指针保存许多子系统.

class System {
public:
    boost::shared_ptr< Subsystem > GetSubsystem( unsigned int index ) {
        assert( index < mSubsystems.size() );
        return mSubsystems[ index ];
    }

    void LogMessage( const std::string& message ) {
        std::cout << message << std::endl;
    }

private:
    typedef std::vector< boost::shared_ptr< Subsystem > > SubsystemList;
    SubsystemList mSubsystems;    
};

class Subsystem {
public:
    Subsystem( System* pParentSystem )
         : mpParentSystem( pParentSystem ) {
    }

    ~Subsystem() {
         pParentSubsystem->LogMessage( "Destroying..." );
         // Destroy this subsystem: deallocate memory, release resource, etc.             
    } …
Run Code Online (Sandbox Code Playgroud)

c++ raii shared-ptr object-lifetime

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

IOptionsMonitor与IOptionsSnapshot之间的区别

根据此答案IOptionsMonitor将以单例形式注册在DI容器中,并且能够通过OnChange事件订阅来检测更改。它有一个CurrentValue属性。

另一方面,通过读取每个请求的最后一个选项IOptionsSnapshot被注册为作用域,并且还具有更改检测功能,但是它没有OnChange事件。它有一个Value属性。

例如,将两者都注入到视图中将为我们提供完全相同的行为:

using Microsoft.AspNetCore.Mvc.RazorPages;
using Microsoft.Extensions.Options;
using UsingOptionsSample.Models;
using UsingOptionsSample.Services;

namespace UsingOptionsSample.Pages
{
    public class MyOptions
    {
        public MyOptions()
        {
            // Set default value.
            Option1 = "value1_from_ctor";
        }

        public string Option1 { get; set; }
        public int Option2 { get; set; } = 5;
    }

    public class OptionsTestModel : PageModel
    {
        private readonly MyOptions _snapshotOptions;
        private readonly MyOptions _monitorOptions;

        public OptionsTestModel( …
Run Code Online (Sandbox Code Playgroud)

dependency-injection interface options object-lifetime asp.net-core

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

在C ++ 17中,malloc是否返回“无效的指针值”?

根据C ++ 17 [basic.compound] / 3:

指针类型的每个值都是以下之一:

  • 指向对象或函数的指针(据说该指针指向对象或函数),或
  • 一个超出对象末尾的指针(8.7),或者
  • 该类型的空指针值(7.11),或者
  • 无效的指针值。

malloc函数返回一个指针值。让我们假设调用成功,因此返回值不为null。malloc([c.malloc])的规范没有声明它在返回的存储中创建了任何对象,因此似乎“无效的指针值”是最没有意义的类别。

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

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

在构造函数中调用虚方法:Java和C++之间的区别

在Java中:

class Base {
    public Base() { System.out.println("Base::Base()"); virt(); }
    void virt()   { System.out.println("Base::virt()"); }
}

class Derived extends Base {
    public Derived() { System.out.println("Derived::Derived()"); virt(); }
    void virt()      { System.out.println("Derived::virt()"); }
}

public class Main {
    public static void main(String[] args) {
        new Derived();
    }
}
Run Code Online (Sandbox Code Playgroud)

这将输出

Base::Base()
Derived::virt()
Derived::Derived()
Derived::virt()
Run Code Online (Sandbox Code Playgroud)

但是,在C++中,结果是不同的:

Base::Base()
Base::virt() // ? Not Derived::virt()
Derived::Derived()
Derived::virt()
Run Code Online (Sandbox Code Playgroud)

(有关C++代码,请参阅http://www.parashift.com/c++-faq-lite/calling-virtuals-from-ctors.html)

什么导致Java和C++之间的这种差异?这是vtable初始化的时间吗?

编辑:我确实理解Java和C++机制.我想知道的是这个设计决定背后的见解.

c++ java virtual-functions object-lifetime vptr

15
推荐指数
3
解决办法
4787
查看次数

绕过一个类的构造函数是合法的还是会导致未定义的行为?

请考虑以下示例代码:

class C
{
public:
    int* x;
};

void f()
{
    C* c = static_cast<C*>(malloc(sizeof(C)));
    c->x = nullptr; // <-- here
}
Run Code Online (Sandbox Code Playgroud)

如果由于任何原因我不得不忍受未初始化的内存(当然,如果可能的话,我会打电话new C()),我仍然可以调用放置构造函数.但是,如果我省略这一点,如上所述,并手动初始化每个成员变量,是否会导致未定义的行为?即绕过构造函数本身未定义的行为,或者用类外的一些等效代码替换调用它是否合法?

(通过另一个完全不同的问题遇到这个问题;要求好奇......)

c++ malloc object-lifetime language-lawyer

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

程序退出期间的函数局部静态初始化

标准对程序退出期间的函数局部静态初始化有什么看法? 编辑:为了清楚起见,我的意思是代码示例中的情况 - 本地静态b是在构造另一个静态之后a构造的(因此应该b在之前销毁a),但b也在a的析构函数期间构造,所以它应该立即销毁吗?后?优?

我没有设法找到有关此事的任何参考资料。

我想知道这种情况是 UB,还是应该有一些定义的行为?

下面的代码就是一个例子:

struct B{};

void foo()
{
    static B b;
}

struct A
{
    ~A() { foo(); }
};

int main()
{
    static A a;
    
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如您所见,A 的析构函数会在程序退出时发生(因为它具有静态存储),并且它会尝试构造 B 静态实例。

我对 C++17 更感兴趣,如果它在这个主题上有什么不同的话。

c++ static object-lifetime language-lawyer

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