我正在深入研究来自Objective-C和Java世界的C ++。 Java给了我所有的OOP知识,Objective-C教给我关于手动内存管理的知识。虽然适应C ++很容易(这种语言肯定不值得拥有它的声誉)但我对一件事感到困惑:
我可以将属性声明为string my_string
或string *my_string
。我知道我需要删除第二个,但是将它声明为指针有什么好处?
答案 0 :(得分:1)
在大多数情况下,使用指针变体完全没有任何好处。
使用它的一个原因是,如果您希望该成员在对象的销毁中存活(如果您不在析构函数中删除它)。然而,这种必要性通常是由糟糕的设计强制执行,因此我会尽量避免这种情况。
另一个原因(以及更可能的原因)是,如果您希望成员可选地未定义(即在构造函数中将成员初始化为NULL / nullptr(c ++ 11),并且每个读取访问权限检查是否指针仍为NULL或实际指向某个值)。这样你可以推迟初始化。然而即使在这种情况下,我建议使用智能指针(c ++ 11中的std :: shared_ptr或c ++ 98中的boost :: shared_ptr)或boost :: optional ......
答案 1 :(得分:1)
人们已经几乎完全回答了,但我想补充一点这样的原因:虽然将变量声明为指针是没用的,但如果它是一个很大的结构并且你必须将它作为参数传递给许多函数,它就会派上用场。递归算法。
strcut sMyStruct
{
// A lot of members
}
// Somewhere in your code
sMyStruct foo;
RecursiveOperation( &foo );
// Somewhere else if you want foo to don't be modified.
void RecursiveOperation( const sMyStruct *pFoo )
{
}
// or...
void RecursiveOperation( sMyStruct *pFoo )
{
}
在这种情况下,拥有* pFoo会使您的代码更快更便宜,即使您可以使用&通过参考有一些更安全,但速度稍慢。 显然我可能错了,但这就是求职者教我的。
答案 2 :(得分:0)
我知道我需要删除第二个
指针并不一定意味着涉及任何动态分配。因此,指针不需要自动为delete
d。
将它声明为指针有什么好处?
根据经验,您应该始终使用自动分配的内存(〜堆栈)。如果您觉得需要使用动态分配的内存(例如,堆栈中没有空间),您就会知道。动态分配的内存也可用于手动控制对象的生命周期,但大部分时间都是危险的:这就是为什么我们有智能指针喜欢std::unique_ptr
和std::shared_ptr
。
在这种特殊情况下,除非你真的需要一个指向std::string
的指针作为字符串的引用(可以是nullptr
),否则我无法看到它。大多数std::string
的实现已经动态存储了char
数组。
答案 3 :(得分:0)
在C ++中,您可以在堆栈或堆上存储变量,当您管理指针时,通常您在堆上并且需要手动进行内存管理。
小对象适合堆栈,大型对象(如非常大的字符串)不适合堆栈,并且可能导致堆栈溢出(堆栈非常小,请参阅编译器以查看堆栈空间)。
std::string
不是堆栈上的大对象,因为它们在内部管理堆上的指针。将字符串声明为指针意味着您通常需要该字符串来引用其他内容。
我可以向你提出的建议是始终避免使用原始指针。首选std::unique_ptr
或std::shared_ptr
。
答案 4 :(得分:0)
无。在C ++中,除非需要,否则使用值而不是指针。哎呀,在大多数情况下你也可以使用引用而不是指针(比如函数调用)。
使用std::string*
毫无意义。
唯一的时间A*
有意义,或者根本就是有用的,就是当你想要为这个基类指针分配A
的子类时。一个例子,使用经典的shape
#include <iostream>
#include <memory>
#include <vector>
class shape
{
public:
virtual ~shape() {}; // required to properly be able to delete base class pointers
virtual bool isRound() const = 0;
virtual const char* name() const = 0;
};
class rectangle : public shape
{
public:
bool isRound() const { return false; }
const char* name() const { return "rectangle"; }
};
class circle : public shape
{
bool isRound() const { return true; }
const char* name() const { return "circle"; }
};
class square : public rectangle
{
const char* name() const { return "square"; }
};
int main()
{
std::vector<std::unique_ptr<shape>> shapes;
shapes.emplace_back(new square());
shapes.emplace_back(new circle());
shapes.emplace_back(new rectangle());
for(const auto& s : shapes)
{
if(s->isRound())
std::cout << s->name() << " is round.\n";
else
std::cout << s->name() << " is not round.\n";
}
}
这里,指针向量只是一个例子,它可能是一个类的成员或其他任何东西。
注意我使用的是std::unique_ptr<shape>
而不是shape*
。了解智能指针。快。
答案 5 :(得分:0)
你必须理解指针是将地址保存到内存位置的东西。它可以保存堆栈和堆中的地址