C++ C++;堆积如山

C++ C++;堆积如山,c++,heap-memory,stack-memory,C++,Heap Memory,Stack Memory,我经常看到这样的声明: class A { private: int a; int b; public: // Ctor + Dtor + methods }; class B { private: int a; int b; public: // Ctor + Dtor + methods }; class C { private: A* aClass; B* bClass; // Other members. pu

我经常看到这样的声明:

class A
{
private:
    int a;
    int b;
public:
    // Ctor + Dtor + methods 
};

class B
{
private:
    int a;
    int b;
public:
    // Ctor + Dtor + methods
};

class C
{
private:
    A* aClass;
    B* bClass;
    // Other members.
public:
    // Ctor + Dtor + methods
};
aClass
bClass
由新操作符动态分配

假设 很多人倾向于在显然没有理由的情况下使用堆。动态分配
A
B
类将减小堆栈上
C
对象的大小。然而,新的操作符是“昂贵的”(执行时间),假设我们对
A
B
中包含的所有变量都有getter和setter,设置或获取
A
和/或
B
的成员将导致一些额外的计算,以便访问
A
B
(取消对
A
B
的引用,然后继续操作)

以下是我的问题:

  • 写以下内容会更好吗

    class C
    {
    private:
        A aClass; 
        B bClass;
        // ....
    }
    
  • 这样处理大型对象会导致堆栈溢出吗

  • 如果编译器不知道
    A*
    B*
    的“真实类型”,他是否能够进行一些优化

编辑
我忘了提到C在这两种情况下都是一种合成(谢谢C.LECLERC)。第一种情况用于实现合成。

好的,如果你制作了一个卡片组和一个卡片类,会怎么样。请看下面

namespace game{

enum Rank{ACE=1,TWO,THREE,FOUR,FIVE,SIX,SEVEN,
               EIGHT,NINE,TEN,JACK,KING,QUEEN};

enum Suit{SPADE,DIAMOND,CLUB,HEART};

Class Card{
 public:
    Card(){
    suit = HEART;
    rank = ACE;
    }

    Card(int s, int r){
      suit = static_cast<Suit>(s);
      rank = static_cast<Rank>(r);
    }
 private:
    Rank rank;
    Suit suit;
};

Class Deck{
      public:
         Deck(int count){
              card = new Card[count];
        }
   // You would need a copy constructor of course but im lazy

       ~Deck() { delete [] card; } // Manually deallocate

         private:
          Card *card;
         };
     }
名称空间游戏{
枚举秩{ACE=1,2,3,4,5,6,7,
八,九,十,杰克,国王,王后;
enum套装{黑桃、钻石、梅花、心脏};
班级卡{
公众:
卡片(){
西装=心;
等级=ACE;
}
卡片(整数s,整数r){
套装=静态铸件;
等级=静态施法(r);
}
私人:
等级;
西服;
};
甲板{
公众:
甲板(整数计数){
卡=新卡[计数];
}
//你当然需要一个复制构造函数,但我很懒
~Deck(){删除[]卡;}//手动解除分配
私人:
卡*卡;
};
}
现在,如果我们转到main并制作一个新的卡片组,这个卡片组将有用户在其中键入的卡片数量。这只是一个我将使用的示例,假设我们制作了52张空白卡片,让我们在卡片组中有一个生成卡片组的函数,使用另一种方法从卡片中生成随机卡片,或者可能是标准卡片组

你问的问题有点奇怪,因为你定义了a和B类,那么什么是“真正的类型”

当然,有些东西比其他东西运行得更快或更慢,比如在数组上使用线性或二进制搜索,一个显然更快

在分配这些对象时,研究内存等的关系

还要密切关注组合、聚合和更多关系


至于堆栈溢出,你是在嵌入式系统上工作,还是在制作一百万个对象,否则你应该没问题!

好吧,如果你制作了一个卡片组和一个卡片类,那该怎么办。看看下面

namespace game{

enum Rank{ACE=1,TWO,THREE,FOUR,FIVE,SIX,SEVEN,
               EIGHT,NINE,TEN,JACK,KING,QUEEN};

enum Suit{SPADE,DIAMOND,CLUB,HEART};

Class Card{
 public:
    Card(){
    suit = HEART;
    rank = ACE;
    }

    Card(int s, int r){
      suit = static_cast<Suit>(s);
      rank = static_cast<Rank>(r);
    }
 private:
    Rank rank;
    Suit suit;
};

Class Deck{
      public:
         Deck(int count){
              card = new Card[count];
        }
   // You would need a copy constructor of course but im lazy

       ~Deck() { delete [] card; } // Manually deallocate

         private:
          Card *card;
         };
     }
名称空间游戏{
枚举秩{ACE=1,2,3,4,5,6,7,
八,九,十,杰克,国王,王后;
enum套装{黑桃、钻石、梅花、心脏};
班级卡{
公众:
卡片(){
西装=心;
等级=ACE;
}
卡片(整数s,整数r){
套装=静态铸件;
等级=静态施法(r);
}
私人:
等级;
西服;
};
甲板{
公众:
甲板(整数计数){
卡=新卡[计数];
}
//你当然需要一个复制构造函数,但我很懒
~Deck(){删除[]卡;}//手动解除分配
私人:
卡*卡;
};
}
现在,如果我们转到main并制作一个新的卡片组,这个卡片组将有用户在其中键入的卡片数量。这只是一个我将使用的示例,假设我们制作了52张空白卡片,让我们在卡片组中有一个生成卡片组的函数,使用另一种方法从卡片中生成随机卡片,或者可能是标准卡片组

你问的问题有点奇怪,因为你定义了a和B类,那么什么是“真正的类型”

当然,有些东西比其他东西运行得更快或更慢,比如在数组上使用线性或二进制搜索,一个显然更快

在分配这些对象时,研究内存等的关系

还要密切关注组合、聚合和更多关系


至于堆栈溢出,您是在嵌入式系统上工作,还是在制作一百万个对象,否则您应该没事!

这取决于。“节省堆栈空间”这不是选择使用动态分配/指针的唯一原因。如果
A
B
是多态类层次结构的基础,那么如果需要虚拟力学,则需要指针类型。@NathanOliver:或者A和B没有默认构造函数,尽管它可以由父构造函数定义。如果在不需要多态性的情况下,那么值比指针更好,以避免将来的复制/删除/内存泄漏问题。第一个代码是聚合关系实现,第二个代码是组合关系实现。这些关系也会导致不同的行为(对象生存期和协同).看看UML关系。这取决于“节省堆栈空间”这不是选择使用动态分配/指针的唯一原因。如果
A
B
是多态类层次结构的基础,那么如果需要虚拟力学,则需要指针类型。@NathanOliver:或者A和B没有默认构造函数,尽管它可以由父构造函数定义。如果在不需要多态性的情况下,值比指针更好,以避免将来的复制/删除/内存泄漏问题。第一个代码是聚合关系实现,第二个代码是组合关系实现。这些关系也会导致不同的行为(对象生存期和共时)。请看一下UML关系。