2010-12-13 68 views
7

我知道C++(two?)中的结构和类之间几乎没有区别。尽管如此,我已经被指示使用结构来定义简单的小东西,比如可能不需要成员函数的节点(尽管我可以在技术上包括包含成员函数)。比如我可能会定义一个节点作为链表类的私有成员如下:我可以在没有定义构造函数的情况下在堆上创建新的结构体吗?

class LinkedList { 
    struct Node { 
    MyObject *data; 
    Node *next; 
    }; 

    Node *list; 

}; 

在这种情况下,然而,是有可能创造这个结构在堆上的一个新的实例,否则我就需要定义一个构造函数?有没有办法在没有新操作员的情况下在堆上创建事物?或者,更好的是:我是否没有必要紧紧地坚持这样一个概念,即不应该为结构定义成员函数?我应该继续并定义一个吗?或者如果我这样做,是否会像承认Node真的是内部类而不是内部结构?我真的应该为这些事情担心吗?哪个更具可读性?

谢谢!

回答

5

然而,在这种情况下,是否可以在堆上创建这个结构的新实例,还是我需要定义一个构造函数?有没有办法在没有新操作员的情况下在堆上创建事物?

如前所述,您可以通过new或malloc在堆上创建新实例。

或者更好的是:我没有必要紧紧地抱住这样一个概念,即我不应该为结构定义成员函数吗?

这是一个更有趣的问题。在C++中,structclass之间的主要(唯一的区别)是 默认访问说明符。也就是说,struct默认为公共访问,class默认为私有访问。在我看来,这是决定你们使用哪一种的区别。基本上,如果用户应该直接访问成员,那么它应该是struct

例如,如果您没有成员函数,那么显然意图是直接访问对象的成员,因此它将是struct。如果对象只是一个小的专用帮助程序来实现其外部类(如您的示例中所示),那么即使它具有成员函数,通常也允许外部类访问其成员等它应该是一个struct。通常使用这些类时,外部类的实现与内部类的实现紧密结合,因此没有理由将其隐藏起来。因此,对于普通的(如std :: pair)对象或那些使用有限的对象(如私人内部类),对成员的默认访问可能是件好事,在这些情况下,我会让它们成为structs

4

的malloc工作正常:

Node *n = (Node*)malloc(sizeof(*n)); 

只记得free()什么malloc() 'd和delete什么new' d。

+1

你应该提到malloc不会运行构造函数,如果有的话。 – 2010-12-13 04:23:32

+0

也免费调用析构函数:) – Arunmu 2010-12-13 04:51:01

+0

并且'calloc'也会做一个'memset(0)' – ruslik 2010-12-13 05:37:45

2

即使你没有定义构造函数,编译器会创建一个默认的,所以你可以使用运营商的“新”:

Node *n = new Node; 

AFAIAC,一个结构是一类,除了它的“公开性“违约是颠倒过来的。

+0

但在我的情况下,结构有指针节点:默认的构造函数会使它们指向NULL吗? – Ziggy 2010-12-13 04:28:46

+0

@Ziggy:不;隐式声明的默认构造函数将使所有的指针成员不被初始化。如果你想让它们初始化,你应该声明你自己的构造函数。 (或者,您可以使用'new'的值初始化形式(也就是'new Node()'))。如果您没有[良好的C++入门书](http://stackoverflow.com/questions/388242/the-definitive-c++-book-guide-and-list),请考虑获取一个。 – 2010-12-13 04:39:31

2

但是,在这种情况下,是否可以在堆上创建此结构的新实例,还是需要定义构造函数?

是的,你可以在没有定义构造函数的情况下在堆上创建它。

有没有办法在没有新操作符的情况下在堆上创建事物?

您可以使用'malloc',并在释放内存时使用'free'。否则就没有其他办法了。

或者更好的是:我没有必要紧紧地抱住我不应该为结构定义成员函数的概念吗?

就个人而言,如果我需要我的结构具有成员函数,我把它改成一个类。我倾向于使用结构,因为可能会在OCaml中使用记录。

1

我真的应该担心这些类型的东西吗?

是的。正如你所说,结构和类之间确实没有重要的区别。如果您被告知要制作struct,并且它至少需要一个成员函数,那么将定义一个成员函数

这真的没什么大不了的。

但除此之外,你当然可以堆分配结构没有构造函数(否则malloc将是毫无意义的C.这语言甚至不已经构造函数)

给出一个struct S,你可以只需拨打new Snew S(),具体取决于您想要的初始化类型。如果你没有定义一个构造函数,编译器会为你制作一个构造函数。

相关问题