为什么对c+使用非指针+;领域? 这些天我开始用C++来解决问题,而且由于我的java ISH背景,我在理解C++方面明显存在一些问题。 因为java只提供引用和原语,对我来说,最神秘的C++特性之一是非指针(非原始)字段。
这是我的意思的一个例子 <>如果我要在C++ C++中实现一个X类对象的列表,我会写一些类似的东西:为什么对c+使用非指针+;领域? 这些天我开始用C++来解决问题,而且由于我的java ISH背景,我在理解C++方面明显存在一些问题。 因为java只提供引用和原语,对我来说,最神秘的C++特性之一是非指针(非原始)字段。,c++,pointers,data-structures,C++,Pointers,Data Structures,这是我的意思的一个例子 如果我要在C++ C++中实现一个X类对象的列表,我会写一些类似的东西: class XList{ private: struct node { X* data; node* next; }; node* first; public: */ a lot of methods */ } 这段代码可能很糟糕,我
class XList{
private:
struct node {
X* data;
node* next;
};
node* first;
public:
*/
a lot of methods
*/
}
这段代码可能很糟糕,我知道模板、STL等等,但我这里的问题只是“数据”字段。如果将“数据”声明为X指针,我认为我可以以非常类似于Java引用的方式使用它
将数据声明为X(X data;)的原因是什么。有什么区别?我知道在堆栈上分配和在堆上分配的区别,但是这里有什么联系吗
请帮我进一步了解这个话题
多谢各位
---更新:----
大多数答案似乎都集中于在指针上使用普通类型与普通类型之间的区别。也许我写这个问题的方式不对,但我已经知道在堆栈或堆上分配的区别(至少是基本的)。 我不能理解的是,在我看来(可能是错误的),在成员变量中使用普通类型(不是字段,谢谢你的更正)应该只是某种特殊情况。特别是当涉及到模板时,数据的副本对我来说毫无意义 相反,每当我看到某个数据结构的实现时,就会使用普通类型 例如:如果你在谷歌上搜索“BST C++模板”,你会发现很多类似这样的实现:
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数据;
};
树节点*根;
公众:
/*
方法、方法和方法
*/
})
您真的想在不知道其大小的情况下复制插入到此树上的每一个T类型的数据吗?由于我不熟悉这门语言,我想我误解了一些东西。使用
X
而不是X*
的优点是,使用指针时,您还必须为X
分配空间,这会占用更多空间(指针为4字节或8字节,加上通过new
为X
分配的开销),而对于普通类型,您可以避免这种开销。因此,仅使用普通X
更简单
当您确实不想复制X
值时,您可能会使用指针,但如果不小心,可能会导致指针悬空。如果在某些情况下您可能没有指向的对象,您也会使用指针
总结
使用
X
而不是X*
的优点是,使用指针时,还必须为X
分配空间,这会占用更多空间(指针为4字节或8字节,加上通过new
为X
分配的开销),而使用普通类型可以避免这种开销。因此,只使用普通X
更简单
当您确实不想复制X
值时,您可能会使用指针,但如果不小心,可能会导致指针悬空。如果在某些情况下您可能没有指向的对象,您也会使用指针
总结
不同之处在于指针指向尚未分配或已确定的大块内存。但当您去掉*时,您的意思是“为整个类(而不仅仅是指向类的指针)以及该类分配了空间。” 前者使用指针,将所有内存分配和维护交给您,后者只将对象作为类的成员提供给您
前者不会占用太多的空间(什么,4到8个字节,取决于体系结构?),后者可以根据类X作为其成员的内容使用少量到大量的空间。不同之处在于指针指向尚未分配或确定的大块内存。但当您取消*时,您会说“为整个类(而不仅仅是指向类的指针)以及该类分配了空间。” 前者使用指针,将所有内存分配和维护交给您,后者只将对象作为类的成员提供给您
前者不会占用太多空间(什么,四到八个字节,取决于体系结构)?后者可以使用一点到很多空间,这取决于类X作为其成员的内容。我在以下情况下使用非指针数据成员:1)我确信这些数据不应该也不会在对象之间共享2)当项目最终销毁时,我可以依靠自动解除分配。一个很好的例子是包装器(要包装的东西):
我在以下情况下使用非指针数据成员:1)我确信这些数据不应该也不会在对象之间共享2)当项目最终销毁时,我可以依靠自动解除分配。一个很好的例子是包装器(要包装的东西):
主要区别在于,如果声明
X*
,则负责堆上的内存管理(new
和delete
),而使用X
则在堆栈上处理内存,因此它是通过作用域分配/释放的
还有其他一些微妙的事情,比如担心任务
class Wrapper
{
private:
Wrapped _wrapped;
public:
Wrapper(args) : _wrapped(args) { }
}