C++ cli 应该是C++/CLI数据成员是句柄还是值?

C++ cli 应该是C++/CLI数据成员是句柄还是值?,c++-cli,C++ Cli,我是C++/CLI新手,我想知道关于托管类型数据成员的“最佳实践”是什么。声明为句柄: public ref class A { public: A() : myList(gcnew List<int>()) {} private: List<int>^ myList; }; public ref A类{ 公众: A():myList(gcnew List()){} 私人: 列表^myList; }; 或作为一个值: public ref class

我是C++/CLI新手,我想知道关于托管类型数据成员的“最佳实践”是什么。声明为句柄:

public ref class A {
public:
    A() : myList(gcnew List<int>()) {}
private:
    List<int>^ myList;
};
public ref A类{
公众:
A():myList(gcnew List()){}
私人:
列表^myList;
};
或作为一个值:

public ref class B {
private:
    List<int> myList;
};
公共参考B类{
私人:
列出我的清单;
};

似乎找不到对此的明确建议。

就我个人而言,我会使用第二种形式。我这样说是因为我使用的框架是由其他团队编写的,他们使用这种形式

我相信这是因为它更干净,占用更少的空间,更容易非作者阅读。我尽量记住,最简洁的代码,同时仍然可以被对项目了解最少的人阅读是最好的

另外,在头文件、方法、类或数据文件等的可读性方面,我没有遇到后一个示例的任何问题

虽然我与这方面的专家相去甚远,但这正是我喜欢的。对我来说更有意义

class AlgoCompSelector : public TSelector {
   public :
   AlgoCompSelector( TTree *tree = 0 );
   virtual ~AlgoCompSelector(){ /* */ };
   virtual void    Init(TTree *tree);
   virtual void    SlaveBegin(TTree *tree);
   virtual Bool_t  Process(Long64_t entry);
   virtual void    Terminate();
   virtual Int_t   Version() const { return 1; }

   void setAlgo( Int_t idx, const Char_t *name, TTree* part2, TTree* part3 );
   void setPTthres( Float_t val );
   void setEthres( Float_t val );                                                                                                                   

   private:
   std::string mAlgoName[2];                  // use this for the axis labels and/or          legend labels.                                         
   TTree *mPart1;
   TTree *mPart2[2], *mPart3[2];     // pointers to TTrees of the various parts                                                              
   TBranch *mPhotonBranch[2];                 // Used branches                                                                               
   TClonesArray *mPhotonArray[2];             // To point to the array in the tree 

例如,就我个人而言,我会使用第二种形式。我这样说是因为我使用的框架是由其他团队编写的,他们使用这种形式

我相信这是因为它更干净,占用更少的空间,更容易非作者阅读。我尽量记住,最简洁的代码,同时仍然可以被对项目了解最少的人阅读是最好的

另外,在头文件、方法、类或数据文件等的可读性方面,我没有遇到后一个示例的任何问题

虽然我与这方面的专家相去甚远,但这正是我喜欢的。对我来说更有意义

class AlgoCompSelector : public TSelector {
   public :
   AlgoCompSelector( TTree *tree = 0 );
   virtual ~AlgoCompSelector(){ /* */ };
   virtual void    Init(TTree *tree);
   virtual void    SlaveBegin(TTree *tree);
   virtual Bool_t  Process(Long64_t entry);
   virtual void    Terminate();
   virtual Int_t   Version() const { return 1; }

   void setAlgo( Int_t idx, const Char_t *name, TTree* part2, TTree* part3 );
   void setPTthres( Float_t val );
   void setEthres( Float_t val );                                                                                                                   

   private:
   std::string mAlgoName[2];                  // use this for the axis labels and/or          legend labels.                                         
   TTree *mPart1;
   TTree *mPart2[2], *mPart3[2];     // pointers to TTrees of the various parts                                                              
   TBranch *mPhotonBranch[2];                 // Used branches                                                                               
   TClonesArray *mPhotonArray[2];             // To point to the array in the tree 

例如,这一切都取决于生命周期。如果您有一个与所属类寿命相同的私有成员,则最好使用第二种形式。

这取决于其寿命。当您有一个与拥有类一样长的私有成员时,第二种形式是更好的。

< P>当编写托管C++代码时,我倾向于遵循其他托管语言所使用的约定。因此,我将使用类级数据成员的句柄,并且仅在C#中使用
using
语句时使用值(堆栈语义)

如果类成员是值,则完全替换该对象意味着该对象需要定义一个副本构造函数,而不是许多.NET类。此外,如果要将对象传递给另一个方法,则需要使用
%
操作符将
列表
转换为
列表^
。(键入
%
没什么大不了的,但很容易忘记,编译器错误只是说它无法将
列表
转换为
列表^

//运算符“%”的示例
void CSharpMethodThatDoesMethingWithList(List^List){}
价值清单;
CSharpMethods不与列表(%valueList)匹配;
List^handleList=gcnewlist();
CSharpMethods,该方法与列表(handleList)不匹配;

编写托管C++代码时,我赞成遵循其他托管语言使用的约定。因此,我将使用类级数据成员的句柄,并且仅在C#中使用

using
语句时使用值(堆栈语义)

如果类成员是值,则完全替换该对象意味着该对象需要定义一个副本构造函数,而不是许多.NET类。此外,如果要将对象传递给另一个方法,则需要使用
%
操作符将
列表
转换为
列表^
。(键入
%
没什么大不了的,但很容易忘记,编译器错误只是说它无法将
列表
转换为
列表^

//运算符“%”的示例
void CSharpMethodThatDoesMethingWithList(List^List){}
价值清单;
CSharpMethods不与列表(%valueList)匹配;
List^handleList=gcnewlist();
CSharpMethods,该方法与列表(handleList)不匹配;

您确定托管类型占用的空间更少吗?不可能在CLR级别将托管类内联到另一个托管类中。当我说空格时,我的意思是空间,而不是内存。我喜欢简洁的代码,这通常意味着更少的内存空间。你确定托管类型的代码占用更少的空间吗?不可能在CLR级别将托管类内联到另一个托管类中。当我说空格时,我的意思是空间,而不是内存。我喜欢简洁的代码,这通常意味着更少的内存空间。这是有意义的,因为它使使用.NET感觉更自然,因为参数通常是句柄。这是有意义的,因为它使使用.NET感觉更自然,因为参数通常是句柄。