在这些日子里,我开始厌倦了c ++,由于我的Java背景,我在理解一些c ++特性时显然遇到了一些问题。
由于java只提供引用和原语,对我来说最神秘的c ++特性之一是非指针(和非原始)字段。
这是我的意思的一个例子。
如果我应该在c ++中编写一个类型为X的对象列表的c ++实现,我会写一些类似的东西:
class XList{
private:
struct node {
X* data;
node* next;
};
node* first;
public:
*/
a lot of methods
*/
}
这段代码可能很糟糕,我知道模板,STL等等,但这里的问题只是字段“数据”。如果将“data”声明为X指针,我假设我可以以非常类似于Java引用的方式使用它。
将数据声明为X(X数据;)的原因可能是什么。有什么不同?我知道在堆栈和堆上分配之间的区别,但是这里有连接吗?
请帮助我更多地掌握这个主题。
谢谢。
---更新:----
大多数答案似乎都集中在一般指针上使用普通类型的区别。
可能我用错误的方式写了这个问题,但我已经知道在堆栈上或在堆上分配之间的区别(至少是基础)。
我无法理解的是,在我(可能是错误的)意见中,在成员变量中使用普通类型(不是字段,感谢您的更正)应该只是某种角落案例。特别是当涉及模板时,数据的副本对我来说毫无意义。
相反,每当我看到某些数据结构的实现时,都会使用普通类型。
例如:如果你在google上搜索“bst c ++ template”,你会发现很多像这样的实现:
template<class T>
class BinarySearchTree
{
private:
struct tree_node
{
tree_node* left;
tree_node* right;
T data;
};
tree_node* root;
public:
/*
methods, methods and methods
*/
};
你真的想要在不知道它的大小的情况下复制插在这棵树上的每种T型数据吗?由于我不熟悉这种语言,我认为我误解了一些东西。
答案 0 :(得分:1)
使用X
而不是X *
的优点是,使用指针时,您还必须为X
分配空间,这会占用更多空间(4个字节)或指针的8个字节,加上X
通过new
分配的开销,而使用普通类型,可以避免这种开销。因此,使用普通X
。
当您明确地不想复制X
值时,您会使用指针,但如果您不小心,最终可能会出现悬挂指针。如果在某些情况下您可能没有要指向的对象,也可以使用指针。
答案 1 :(得分:0)
不同之处在于指针指向尚未分配或确定的内存块。但是当你离开*时,你会说“为这整个班级分配了空间(不只是指向一个班级的指针)”。
前者使用指针将所有内存分配和维护放在手中。后者只是将对象作为您班级的成员。
前者不占用太多空间(四到八个字节,取决于架构?)后者可以使用一点点LOT,具体取决于X类的成员。
答案 2 :(得分:0)
我在以下情况下使用非指针数据成员:1)我确定这些数据不应该也不会在对象之间共享2)当oject最终被销毁时,我可以依赖自动释放。一个很好的例子是包装器(要包装的东西):
class Wrapper
{
private:
Wrapped _wrapped;
public:
Wrapper(args) : _wrapped(args) { }
}
答案 3 :(得分:0)
主要区别在于,如果您声明X*
,则负责堆上的内存管理(new
和delete
),而使用X
内存在堆栈上处理,因此它使用作用域进行分配/释放。
还有其他微妙的事情,比如担心分配给自己等等。