在本文中,我们将给您介绍关于通用约束,其中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(通用约束条件和限制条件)
- .NET中的struct和class有什么区别?
- C ++中的struct和class有什么区别?
- C struct 简单实现 class
- C struct和typdef
通用约束,其中T:struct和T:class(通用约束条件和限制条件)
我想区分以下几种情况:
- 普通值类型(例如
int
) - 可为空的值类型(例如
int?
) - 引用类型(例如
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有什么区别?
#1楼
除了其他答案中描述的所有差异之外:
- 结构不能具有显式的无参数构造函数,而类可以
- 结构不能有析构函数 ,而类可以
- 结构不能从另一个结构或类继承,而一个类可以从另一个类继承。 (结构和类都可以从接口实现。)
如果您正在观看解释所有差异的视频,则可以查看第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#/。Net上下文中提出过 。
现在,我想学习C ++中的结构和类之间的区别。 请讨论技术差异以及在OO设计中选择一个或另一个的原因。
我将从一个明显的区别开始:
- 如果您未指定
public:
或private:
:,则结构的成员默认为public; 默认情况下,类的成员是私有的。
我确信在C ++规范的晦涩之处可以找到其他差异。
#1楼
- 默认情况下,结构的成员是公共的,而默认情况下,类的成员是私有的。
- 从另一个结构或类的结构的默认继承是公共的。从另一个结构或类的结构的默认继承是私有的。
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楼
。 在类中,默认情况下所有成员都是私有的,而在结构中默认情况下所有成员都是公共的。
对于结构,没有像构造函数和析构函数这样的术语,但是对于类编译器,如果不提供,则会创建默认值。
空类的Sizeof结构为0字节,而空类的Sizeof为1字节结构的默认访问类型为public。 通常应将结构用于分组数据。
类的默认访问类型为private,继承的默认模式为private。 应该使用一个类对数据和对该数据进行操作的方法进行分组。
简而言之,约定是在将数据分组时使用struct,而在我们需要数据抽象甚至继承的情况下使用类。
在C ++中,除非明确取消引用,否则结构和类将按值传递。 在其他语言中,类和结构可能具有不同的语义-即。 对象(类的实例)可以通过引用传递,而结构可以通过值传递。 注意:有与此问题相关的评论。 请参阅讨论页添加到对话。
#3楼
C ++中struct和class关键字之间的区别在于,当在特定的复合数据类型上没有特定的说明符时,默认情况下struct或union是仅考虑数据隐藏的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类型的变量
- myClassObject1
- 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来写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
我试图理解下面链接中的代码.
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_包装器的原因是因为无法表达返回指向同一类型函数的指针的函数.包装器摆脱了自我引用.
逐行:
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的相关知识,请在本站搜索。
本文标签: