标签: struct

为什么.NET中没有RAII?

作为一名C++开发人员,Java和.NET中缺少RAII(资源获取是初始化)一直困扰着我.清理的责任从班级作者转移到其消费者(通过try finally.NET的using构造)这一事实似乎显然是劣等的.

我明白为什么在Java中不支持RAII,因为所有对象都位于堆上,而垃圾收集器本身并不支持确定性破坏,但在.NET中引入了values-types(struct)我们有(看似) RAII的完美候选人.在堆栈上创建的值类型具有明确定义的范围,并且可以使用C++析构函数语义.但是,CLR不允许值类型具有析构函数.

我的随机搜索发现了一个论点,如果一个值类型被装箱,它就属于垃圾收集器的管辖范围,因此它的破坏变得不确定.我觉得这个论点不够强大,RAII的好处足以说明带有析构函数的值类型不能被装箱(或用作类成员).

简而言之,我的问题是:为了将RAII引入.NET,是否有任何其他原因无法使用值类型?(或者您认为我关于RAII明显优势的论点有缺陷吗?)

编辑:我必须没有明确表达这个问题,因为前四个答案已经错过了重点.我知道关于Finalize其不确定性的特点,我知道的using结构,我觉得这两个选项都逊色于RAII.using是一个阶级的消费者必须记住的另一件事(有多少人忘了把它StreamReader放在一个using街区?).我的问题是关于语言设计的哲学问题,为什么它是这样的,它可以改进吗?

例如,对于通用的确定性可破坏的值类型,我可以使usinglock关键字冗余(可以通过库类实现):

    public struct Disposer<T> where T : IDisposable
    {
        T val;
        public Disposer(T t) { val = t; }
        public T Value { get { return val; } }
        ~Disposer()  // Currently illegal 
        {
            if (val != default(T))
                val.Dispose();
        }
    }
Run Code Online (Sandbox Code Playgroud)

我忍不住以我曾经看过的apropos报价结束,但目前无法找到它的起源.

当我的冷死手超出范围时,你可以采取我的确定性破坏.- 匿名

.net struct destructor raii value-type

64
推荐指数
3
解决办法
7974
查看次数

自动属性和结构不混合?

在回答这篇文章的同时踢了一些小结构,我意外地遇到了以下情况:

使用int字段的以下结构是完全合法的:

struct MyStruct
{ 
    public MyStruct ( int size ) 
    { 
        this.Size = size; // <-- Legal assignment.
    } 

    public int Size; 
}
Run Code Online (Sandbox Code Playgroud)

但是,使用自动属性的以下结构无法编译:

struct MyStruct
{ 
    public MyStruct ( int size ) 
    { 
        this.Size = size; // <-- Compile-Time Error!
    } 

    public int Size{get; set;}
}
Run Code Online (Sandbox Code Playgroud)

返回的错误是"在将所有字段分配给"之前,不能使用'this'对象.我知道这是结构的标准过程:任何属性的支持字段必须直接从结构的构造函数中指定(而不是通过属性的set访问器).

解决方案是使用显式支持字段:

struct MyStruct
{ 
    public MyStruct(int size)
    {
        _size = size;
    }

    private int _size;

    public int Size
    {
        get { return _size; }
        set { _size = value; …
Run Code Online (Sandbox Code Playgroud)

c# struct automatic-properties c#-3.0

64
推荐指数
3
解决办法
2万
查看次数

如何使用匿名结构/联合编译C代码?

我可以用c ++/g ++做到这一点:

struct vec3 { 
    union {
        struct {
            float x, y, z;
        }; 
        float xyz[3];
    }; 
};
Run Code Online (Sandbox Code Playgroud)

然后,

vec3 v;
assert(&v.xyz[0] == &v.x);
assert(&v.xyz[1] == &v.y);
assert(&v.xyz[2] == &v.z);
Run Code Online (Sandbox Code Playgroud)

将工作.

如何使用gcc在c中执行此操作?我有

typedef struct {
    union {
        struct {
            float x, y, z;
        };
        float xyz[3];
    };
} Vector3;
Run Code Online (Sandbox Code Playgroud)

但我特别是周围都有错误

line 5: warning: declaration does not declare anything
line 7: warning: declaration does not declare anything
Run Code Online (Sandbox Code Playgroud)

c c++ struct anonymous unions

64
推荐指数
5
解决办法
8万
查看次数

关键字"new"对C#中的结构有什么作用?

在C#中,结构是根据值进行管理的,对象是引用的.根据我的理解,在创建类的实例时,关键字new会导致C#使用类信息来创建实例,如下所示:

class MyClass
{
    ...
}
MyClass mc = new MyClass();
Run Code Online (Sandbox Code Playgroud)

对于struct,您不是创建对象而只是将变量设置为值:

struct MyStruct
{
    public string name;
}
MyStruct ms;
//MyStruct ms = new MyStruct();     
ms.name = "donkey";
Run Code Online (Sandbox Code Playgroud)

我不明白的是,如果声明变量by MyStruct ms = new MyStruct(),new这里的关键字是什么?.如果struct不能成为对象,那么new这里实例化是什么?

c# struct object

64
推荐指数
3
解决办法
3万
查看次数

C++语法"A :: B:A {};"是什么意思

C++语法struct A::B:A {};是什么意思?C++标准中描述的名称定义(或访问)在哪里?

#include <iostream>

struct B;

struct A {
    struct B;
};

struct A::B:A {
};

int main() {
    A::B::A::B b;
    std::cout<<"Sizeof A::B::A::B is " << sizeof(A::B::A::B)<<std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

c++ syntax struct scope-resolution

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

memset()或值初始化将结构清零?

在Win32 API编程中,通常使用struct具有多个字段的C s.通常只有其中几个具有有意义的值,而其他所有值都必须归零.这可以通过以下两种方式之一实现:

STRUCT theStruct;
memset( &theStruct, 0, sizeof( STRUCT ) );
Run Code Online (Sandbox Code Playgroud)

要么

STRUCT theStruct = {};
Run Code Online (Sandbox Code Playgroud)

第二个变体看起来更干净 - 它是一个单行,它没有任何可能输错的参数并导致错误被种植.

与第一个变体相比,它有任何缺点吗?使用哪种变体?为什么?

c c++ struct initialization visual-c++

63
推荐指数
6
解决办法
7万
查看次数

C vs C++ struct alignment

我在最近的一次采访中被问到有关C++结构字段对齐的问题,并且理论上C和C++在结构打包中遵循相同的策略.

Hovewer,这是错误的假设.采访者说,一般来说,C和C++以不同的方式包装结构,我们永远不应该期待相反的结果.恕我直言,这是一个奇怪的声明.pack "C"在C++中没有用于双语C/C++头文件的结构限定符.

因此在实践中,它可能意味着您无法在C++中创建结构并将其传递给C库,因为通常它的字段将以不同的方式对齐并具有不同的偏移量.但实际上,大多数程序员都非常依赖这种互操作性,直到他们将一个指向C POD结构的指针转换为对这个结构的C++包装器的引用,并使用了一些辅助方法.你能澄清一下这个问题吗?

c c++ struct pointers object-layout

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

更改结构列表中元素的值

我有一个结构列表,我想改变一个元素.例如 :

MyList.Add(new MyStruct("john");
MyList.Add(new MyStruct("peter");
Run Code Online (Sandbox Code Playgroud)

现在我想改变一个元素:

MyList[1].Name = "bob"
Run Code Online (Sandbox Code Playgroud)

但是,每当我尝试这样做时,我都会收到以下错误:

无法修改System.Collections.Generic.List.this [int]'的返回值,因为它不是变量

如果我使用类列表,则不会出现问题.

我想答案与结构是一种值类型有关.

那么,如果我有一个结构列表,我应该将它们视为只读吗?如果我需要更改列表中的元素,那么我应该使用类而不是结构?

c# struct value-type

61
推荐指数
5
解决办法
8万
查看次数

使用C++中的模板变量进行结构化

我正在玩模板.我不是要重新发明std :: vector,我试图掌握C++中的模板.

我可以这样做吗?

template <typename T>
typedef struct{
  size_t x;
  T *ary;
}array;
Run Code Online (Sandbox Code Playgroud)

我想要做的是一个基本的模板化版本:

typedef struct{
  size_t x;
  int *ary;
}iArray;
Run Code Online (Sandbox Code Playgroud)

如果我使用类而不是struct,它看起来像是有效的,所以使用typedef结构是不可能的?

c++ templates struct class

61
推荐指数
4
解决办法
12万
查看次数

隐藏C结构中的成员

我一直在读C中的OOP,但我从来不喜欢你不能在C++中拥有像你这样的私人数据成员.但后来我想到你可以创建2个结构.一个在头文件中定义,另一个在源文件中定义.

// =========================================
// in somestruct.h
typedef struct {
  int _public_member;
} SomeStruct;

// =========================================
// in somestruct.c

#include "somestruct.h"

typedef struct {
  int _public_member;
  int _private_member;
} SomeStructSource;

SomeStruct *SomeStruct_Create()
{
  SomeStructSource *p = (SomeStructSource *)malloc(sizeof(SomeStructSource));
  p->_private_member = 42;
  return (SomeStruct *)p;
}
Run Code Online (Sandbox Code Playgroud)

从这里你可以将一个结构投射到另一个结构.这被认为是不好的做法吗?还是经常这样做?

c struct private-members

61
推荐指数
6
解决办法
3万
查看次数