GVKun编程网logo

通用约束,其中T:struct和T:class(通用约束条件和限制条件)

27

在本文中,我们将给您介绍关于通用约束,其中T:struct和T:class的详细内容,并且为您解答通用约束条件和限制条件的相关问题,此外,我们还将为您提供关于.NET中的struct和class有什么

在本文中,我们将给您介绍关于通用约束,其中T:struct和T:class的详细内容,并且为您解答通用约束条件和限制条件的相关问题,此外,我们还将为您提供关于.NET中的struct和class有什么区别?、C ++中的struct和class有什么区别?、C struct 简单实现 class、C struct和typdef的知识。

本文目录一览:

通用约束,其中T:struct和T:class(通用约束条件和限制条件)

通用约束,其中T:struct和T:class(通用约束条件和限制条件)

我想区分以下几种情况:

  1. 普通值类型(例如int
  2. 可为空的值类型(例如int?
  3. 引用类型(例如string)-可选,我不在乎是否将其映射到上面的(1)或(2)

我想出了以下代码,在情况(1)和(2)下工作正常:

static void Foo<T>(T a) where T : struct { } // 1static void Foo<T>(T? a) where T : struct { } // 2

但是,如果我尝试检测这种情况(3),它将无法编译:

static void Foo<T>(T a) where T : class { } // 3

错误消息是 类型’X’已经定义了具有相同参数类型的成员’Foo’ 。好吧,我无法以where T : struct和区别where T :class

如果删除第三个函数(3),则以下代码也不会编译:

int x = 1;int? y = 2;string z = "a";Foo (x); // OK, calls (1)Foo (y); // OK, calls (2)Foo (z); // error: the type ''string'' must be a non-nullable value type ...

如何Foo(z)进行编译,将其映射到上述函数之一(或第三个具有另一个约束的函数,我没有想到)?

答案1

小编典典

约束不是签名的一部分,但参数是签名的一部分。在重载解析过程中会强制执行参数约束。

因此,让我们将约束放入参数中。很难看,但是可以用。

class RequireStruct<T> where T : struct { }class RequireClass<T> where T : class { }static void Foo<T>(T a, RequireStruct<T> ignore = null) where T : struct { } // 1static void Foo<T>(T? a) where T : struct { } // 2static void Foo<T>(T a, RequireClass<T> ignore = null) where T : class { } // 3

(迟到比没有迟到六年吗?)

.NET中的struct和class有什么区别?

.NET中的struct和class有什么区别?

.NET中的struct和class有什么区别?


#1楼

除了其他答案中描述的所有差异之外:

  1. 结构不能具有显式的无参数构造函数,而类可以
  2. 结构不能有析构函数 ,而类可以
  3. 结构不能从另一个结构或类继承,而一个类可以从另一个类继承。 (结构和类都可以从接口实现。)

如果您正在观看解释所有差异的视频,则可以查看第29部分-C#教程-C#中的类和结构之间的差异


#2楼

好吧,对于初学者来说,结构是通过值而不是通过引用传递的。 结构适合于相对简单的数据结构,而从架构的角度来看,通过多态和继承,类具有更大的灵活性。

其他人可能会给您比我更多的细节,但是当我要使用的结构很简单时,我会使用结构。


#3楼

在.NET中,结构和类声明区分引用类型和值类型。

当您绕过一种引用类型时,实际上仅存储一种。 所有访问该实例的代码都在访问同一代码。

当您传递一个值类型时,每个值类型都是一个副本。 所有代码都在自己的副本上工作。

可以用一个示例显示:

struct MyStruct 
{
    string MyProperty { get; set; }
}

void ChangeMyStruct(MyStruct input) 
{ 
   input.MyProperty = "new value";
}

...

// Create value type
MyStruct testStruct = new MyStruct { MyProperty = "initial value" }; 

ChangeMyStruct(testStruct);

// Value of testStruct.MyProperty is still "initial value"
// - the method changed a new copy of the structure.

对于一堂课,这将是不同的

class MyClass 
{
    string MyProperty { get; set; }
}

void ChangeMyClass(MyClass input) 
{ 
   input.MyProperty = "new value";
}

...

// Create reference type
MyClass testClass = new MyClass { MyProperty = "initial value" };

ChangeMyClass(testClass);

// Value of testClass.MyProperty is now "new value" 
// - the method changed the instance passed.

类不能为空-引用可以指向null。

结构是实际值-它们可以为空,但不能为null。 因此,结构始终具有不带参数的默认构造函数-它们需要一个“起始值”。


#4楼

类的实例存储在托管堆上。 所有“包含”实例的变量只是对堆上实例的引用。 将对象传递给方法会导致传递引用的副本,而不是对象本身。

结构(从技术上讲,值类型)存储在任何使用它们的位置,就像原始类型一样。 内容可以在运行时随时复制,而无需调用自定义的复制构造函数。 将值类型传递给方法涉及再次复制整个值,而无需调用任何可自定义的代码。

C ++ / CLI名称使区分更好:“ ref class”是第一个描述的类,“ value class”是第二个描述的类。 C#使用的关键字“类”和“结构”只是必须学习的东西。


#5楼

结构是实际值-它们可以为空,但不能为null

的确如此,但是还请注意,从.NET 2开始,结构支持Nullable版本,并且C#提供了一些语法糖以使其易于使用。

int? value = null;
value  = 1;

C ++中的struct和class有什么区别?

C ++中的struct和class有什么区别?

这个问题已经在C#/。Net上下文中提出过 。

现在,我想学习C ++中的结构和类之间的区别。 请讨论技术差异以及在OO设计中选择一个或另一个的原因。

我将从一个明显的区别开始:

  • 如果您未指定public:private: :,则结构的成员默认为public; 默认情况下,类的成员是私有的。

我确信在C ++规范的晦涩之处可以找到其他差异。


#1楼

  1. 默认情况下,结构的成员是公共的,而默认情况下,类的成员是私有的。
  2. 从另一个结构或类的结构的默认继承是公共的。从另一个结构或类的结构的默认继承是私有的。
class A{    
public:    
    int i;      
};

class A2:A{    
};

struct A3:A{    
};


struct abc{    
    int i;
};

struct abc2:abc{    
};

class abc3:abc{
};


int _tmain(int argc, _TCHAR* argv[])
{    
    abc2 objabc;
    objabc.i = 10;

    A3 ob;
    ob.i = 10;

    //A2 obja; //privately inherited
    //obja.i = 10;

    //abc3 obss;
    //obss.i = 10;
}

这是在VS2005上。


#2楼

  • 。 在类中,默认情况下所有成员都是私有的,而在结构中默认情况下所有成员都是公共的。

    1. 对于结构,没有像构造函数和析构函数这样的术语,但是对于类编译器,如果不提供,则会创建默认值。

    2. 空类的Sizeof结构为0字节,而空类的Sizeof为1字节结构的默认访问类型为public。 通常应将结构用于分组数据。

    类的默认访问类型为private,继承的默认模式为private。 应该使用一个类对数据和对该数据进行操作的方法进行分组。

    简而言之,约定是在将数据分组时使用struct,而在我们需要数据抽象甚至继承的情况下使用类。

    在C ++中,除非明确取消引用,否则结构和类将按值传递。 在其他语言中,类和结构可能具有不同的语义-即。 对象(类的实例)可以通过引用传递,而结构可以通过值传递。 注意:有与此问题相关的评论。 请参阅讨论页添加到对话。


#3楼

C ++中structclass关键字之间的区别在于,当在特定的复合数据类型上没有特定的说明符时,默认情况下structunion是仅考虑数据隐藏的public关键字,而class是考虑程序隐藏的private关键字。代码或数据。 总是有些程序员为了代码而使用struct来存储数据和使用 。 有关更多信息,请联系其他来源。


#4楼

从所有这些因素中,可以得出结论,概念类非常适合表示现实世界的对象,而不是“结构”。很大程度上,因为类中使用的OOP概念在解释现实世界场景时非常实用,因此更容易将它们合并为现实。例如,默认继承是结构的公共属性,但是如果将此规则应用于现实世界,这是很荒谬的。但是在类中,默认继承是private,这是更现实的做法。

无论如何,我需要证明的是,类是一个更广泛的,在现实世界中适用的概念,而结构是一个内部组织较差的原始概念(Eventhough结构遵循OOP概念,它们的含义很差)。


#5楼

类是引用类型,结构是值类型。
当我说类是引用类型时,
基本上,它们将包含实例变量的地址。

例如:

Class MyClass
{
    Public Int DataMember;  //By default, accessibility of class data members 
                            //will be private. So I am making it as Public which 
                            //can be accessed outside of the class.
}

在主要方法中
我可以使用为该类分配内存的新运算符创建该类的实例
并将其基地址存储到MyClass类型变量(_myClassObject2)中。

Static Public void Main (string[] arg)
{
    MyClass _myClassObject1 = new MyClass();
    _myClassObject1.DataMember = 10;

    MyClass _myClassObject2 = _myClassObject1;
    _myClassObject2.DataMember=20;
}

在上面的程序中,MyClass _myClassObject2 = _myClassObject1; 指令指示两个MyClass类型的变量

  1. myClassObject1
  2. myClassObject2

并将指向相同的内存位置。
它基本上将相同的内存位置分配给另一个相同类型的变量。

因此,如果我们对MyClass类型的任何一个对象进行的任何更改都会对另一个对象产生影响
因为两者都指向相同的存储位置。

“ _myClassObject1.DataMember = 10;” 在此行,对象的两个数据成员都将包含值10。
“ _myClassObject2.DataMember = 20;” 在此行,对象的数据成员都将包含值20。
最终, 我们通过指针访问对象的数据成员。

与类不同,结构是值类型。 例如:

Structure MyStructure
{
    Public Int DataMember;  //By default, accessibility of Structure data 
                            //members will be private. So I am making it as 
                            //Public which can be accessed out side of the structure.
}

Static Public void Main (string[] arg)
{
    MyStructure _myStructObject1 = new MyStructure();
    _myStructObject1.DataMember = 10;

    MyStructure _myStructObject2 = _myStructObject1;
    _myStructObject2.DataMember = 20;
}

在上面的程序中
使用new运算符实例化MyStructure类型的对象
将地址存储到MyStructure类型的_myStructObject变量中,并
使用“ _myStructObject1.DataMember = 10”将值10分配给结构的数据成员。

在下一行中
我声明了另一个MyStructure类型的变量_myStructObject2,并将_myStructObject1分配给它。
.NET C#编译器在这里创建_myStructureObject1对象的另一个副本,并
将该内存位置分配给MyStructure变量_myStructObject2。

因此,无论我们对_myStructObject1进行的更改如何,都永远不会对MyStructrue类型的另一个变量_myStructObject2产生影响。
这就是为什么我们说结构是值类型。

因此,该类的直接基类是Object,而Structure的直接基类是ValueType,它从Object继承。
类将支持继承,而结构则不支持。

我们怎么说呢?
那是什么原因呢?
答案是班级。

它可以是抽象的,密封的,静态的和部分的,并且不能是私有的,受保护的和受保护的内部。

C struct 简单实现 class

C struct 简单实现 class

以车为对象,用C来写C++的class车。
在C中没有类,所以用struct来代替,

而class中对应的类对象函数就用函数指针来代替。

typedef struct Car
{
    char brand[15]; 	//名称
    int spend;			//速度
    int power;			//功率
    float accelerate;	//加速
    float oil;			//油耗
    void (*Initialization)(struct Car *c,char *s);	//初始化函数,相当于构造
    void (*veiwSpend)(struct Car *c);				//显示当前速度
    void (*Vehicleinformation)(struct Car *c);		//显示车辆信息
    void (*changeSpend)(struct Car *c,int sp);		//改变当前速度
}Car;

每一个类对象函数都需要至少一个参数 (struct Car 的指针),也相当与class中的this指针。

在C++中每个实例化对象都不相同,如何通过调用相同的函数实现对不同实例化对象的操作?
其实就是通过this指针,每一个class对象都有一个this指针,而在对应函数的参数中也包括this指针这个隐藏参数。

初始化函数,相当于构造函数,在这里完成各个数据的初始化(准确来说是赋值,赋值!=初始化)。

void Ini(struct Car *c,char *s)  // s为车辆信息
{
    int i = 0;
    while(s[i]!='\0')
    {
        c->brand[i] = s[i];
        i++;
    }
    c->brand[i] = '\0';   //初始名称 
    c->oil =7.55; 	
    c->spend = 0;
    c->power = 190;
    c->accelerate = 6.9;
    c->changeSpend = Change;			//对应 相应的函数
    c->Vehicleinformation = Vehicle;
    c->veiwSpend = Spend;
}

其他函数。

void Spend(struct Car *c)
{
    int sp = 0;
    sp = c->spend;
    printf("当前时速:%dkm/h\n\n",sp);
}
void Vehicle(struct Car *c)
{
    printf("品牌:%s\n",c->brand);
    printf("最大功率:%dkW\n",c->power);
    printf("油耗:%.2fL/100km\n",c->oil);
    printf("加速:%.2fs/100km\n\n",c->accelerate);
}
void Change(struct Car *c,int sp)
{
    c->spend = sp;
    printf("时速改变成功\n\n");
}

所有代码

#include <stdio.h>
#include <stdlib.h>
typedef struct Car
{

    char brand[15];
    int spend;
    int power;
    float accelerate;
    float oil;
    void (*Initialization)(struct Car *c,char *s);
    void (*veiwSpend)(struct Car *c);
    void (*Vehicleinformation)(struct Car *c);
    void (*changeSpend)(struct Car *c,int sp);
}Car;
void Spend(struct Car *c)
{
    int sp = 0;
    sp = c->spend;
    printf("当前时速:%dkm/h\n\n",sp);
}
void Vehicle(struct Car *c)
{
    printf("品牌:%s\n",c->brand);
    printf("最大功率:%dkW\n",c->power);
    printf("油耗:%.2fL/100km\n",c->oil);
    printf("加速:%.2fs/100km\n\n",c->accelerate);
}
void Change(struct Car *c,int sp)
{
    c->spend = sp;
    printf("时速改变成功\n\n");
}
void Ini(struct Car *c,char *s)
{
    int i = 0;
    while(s[i]!='\0')
    {
        c->brand[i] = s[i];
        i++;
    }
    c->brand[i] = '\0';
    c->oil =7.55;
    c->spend = 0;
    c->power = 190;
    c->accelerate = 6.9;
    c->changeSpend = Change;
    c->Vehicleinformation = Vehicle;
    c->veiwSpend = Spend;
}
int main()
{
    struct Car Benz;
    Benz.Initialization = Ini;

    Benz.Initialization(&Benz,"Benz E3000");
    Benz.Vehicleinformation(&Benz);
    Benz.veiwSpend(&Benz);
    Benz.changeSpend(&Benz,120);
    Benz.veiwSpend(&Benz);

    return 0;
}

大功告成,从这里其实也可以知道虚函数的实现方式,

为什么虚函数可以通过相同的指针调用不同的函数?

虚函数所对应的虚函数表在构造函数中生成,而它们的表对应着不同的函数,通过类中的构造函数自动生成,是哪种构造函数,对应就能使用哪一类函数。

所以如果有人问虚函数包不包括构造? 那肯定不行啊!;

C struct和typdef

C struct和typdef

我不确定标题,因为我不知道它的真正含义.

我试图理解下面链接中的代码.

Color Based Particle Filter

我一般都了解程序的功能,但我无法弄清楚“state.h”.这段代码有什么作用?特别是“typedef”,“State_”和“pp”部分对我来说看起来很陌生.

为清楚起见,我会在这里放一些代码.

struct StateData;
struct State_;
typedef State_ (*State)(StateData&);
struct State_
{
    State_( State pp ) : p( pp ) { }
    operator State()
    {
        return p;
    }
    State p;
};

State_ state_start(StateData& d);
State_ state_selecting(StateData& d);
State_ state_initializing(StateData& d);
State_ state_tracking(StateData& d);

任何形式的帮助将不胜感激.

解决方法

简明扼要:State是函数pointer的别名.State_是一个包装类,它有一个State成员,可以隐式转换为该State.

需要State_包装器的原因是因为无法表达返回指向同一类型函数的指针的函数.包装器摆脱了自我引用.

逐行:

struct StateData;

类StateData的前向声明.

struct State_;

类State_的前向声明.

typedef State_ (*State)(StateData&);

这个有点棘手.它将State定义为函数指针的类型别名,该函数指针可以指向返回State_并获取StateData&的函数.作为一个论点.在代码片段末尾声明的函数可以由此类型的函数指针指向.

在我看来,考虑到已经存在State_类,所选择的名称非常混乱.虽然我通常反对匈牙利表示法,但我建议总是应用后缀或前缀来表示函数指针,比如state_fun或state_handler或state_callback,

struct State_
{

这开始了State_calss的定义.

State_( State pp ) : p( pp ) { }

这定义了类的构造函数.参数是先前定义的函数指针类型.它初始化将很快声明的成员.

operator State()
    {
        return p;
    }

会员功能.更具体地说,用户定义了转换为函数指针类型.

State p;

声明在构造函数中初始化的成员.

};

State_ state_start(StateData& d);
State_ state_selecting(StateData& d);
State_ state_initializing(StateData& d);
State_ state_tracking(StateData& d);

免费功能,可由国家指出.

今天关于通用约束,其中T:struct和T:class通用约束条件和限制条件的讲解已经结束,谢谢您的阅读,如果想了解更多关于.NET中的struct和class有什么区别?、C ++中的struct和class有什么区别?、C struct 简单实现 class、C struct和typdef的相关知识,请在本站搜索。

本文标签: