C++属性声明
C++ property declaration
我正在深入研究来自Objective-C和Java世界的C++。Java给了我所有的OOP知识,Objective-C教会了我手动内存管理。虽然适应C++很容易(该语言绝对配不上它的声誉),但我对一件事感到困惑:
我可以将属性声明为 string my_string
或 string *my_string
.我知道我需要删除第二个,但是将其声明为指针有什么好处?
在大多数情况下,使用指针变体根本没有任何好处。
使用此方法的一个原因是,如果希望成员在对象销毁后幸存下来(如果不在析构函数中删除它)。然而,这种必要性通常是由糟糕的设计强制执行的,所以我会尽量避免这种情况。
另一个原因(也是更可能的原因)是,如果您希望成员可以选择未定义(即在构造函数中将成员初始化为 NULL/nullptr(c++11),并且每个读取访问权限都会检查指针是否仍为 NULL 或实际指向一个值)。这样,您可以推迟初始化。然而,即使在这种情况下,我也建议使用智能指针(c++11 中的 std::shared_ptr 或 c++98 中的 boost::shared_ptr)或 boost::optional...
人们几乎完全回答了这个问题,但我要补充这个原因:虽然将变量声明为指针是无用的,但如果它是一个大结构并且你必须将其作为参数传递给许多函数,比如递归算法,它会派上用场。
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 会使你的代码更快、更便宜,即使你可以使用 & 来传递具有更多安全性但速度稍慢的引用。显然我可能是错的,但这就是同事教我的。
我知道我需要删除第二个
指针并不一定意味着涉及任何动态分配。因此,指针不会自动delete
d。
将其声明为指针有什么优势?
根据经验,您应该始终使用自动分配的内存(~ 堆栈)。如果您觉得需要使用动态分配的内存(例如堆栈中空间不足),您就会知道。动态分配的内存也可用于手动控制对象的生存期,但这在大多数情况下都很危险:这就是为什么我们有像 std::unique_ptr
和 std::shared_ptr
这样的智能指针。
在这种特殊情况下,除非你真的需要一个指向std::string
的指针作为对字符串的引用(可以nullptr
),否则我看不出它的用途。大多数std::string
的实现已经动态存储了char
数组。
C++您可以将变量存储在堆栈或堆上,当您管理指针时,通常您在堆上,您需要手动进行内存管理。
小对象对栈有好处,像非常大的字符串这样的大对象对栈不利,会导致栈溢出(栈很小,看你编译器看栈空间)。
std::string
不是堆栈上的巨大对象,因为它们在内部管理堆上的指针。将字符串声明为指针意味着通常需要该字符串来引用其他内容。
我能建议你总是避免原始指针。更喜欢std::unique_ptr
或std::shared_ptr
。
什么都没有。在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*
。了解智能指针。快。
您必须了解指针是将地址保存到内存位置的东西。它可以保存堆栈和堆中的地址
- 警告:忽略模板参数上的属性..在 std::unique_ptr (-wignore 属性)的声明中
- 在C++/Cython中,是否可以只声明相关属性在Python中可见
- 如何在C++中用属性声明COM接口
- 在 clang 和 gcc 中是否有视觉C++ __declspec(属性声明属性)的替代方案?
- 为什么结构属性声明和初始化顺序的行为是这样的?
- 应用于类型别名声明的 [[maybe_unused]] 属性的语法
- 兼容的声明 __attribute__ ((节( ".abc.dfe" ))) 常量易失性 uint8 属性变量 = 0;- 符合MISRA标准
- C 1Z标准如何定义模板功能声明中属性的正确位置
- 通过"a pointer of the base class"访问未在基类中声明的子类的方法或属性(动态)
- 默认声明的属性?(状态设计模式)
- 声明仅在C 中使用读取属性的接口
- 如何声明 noexcept 如果只有属性的成员函数是 noexcept
- 为什么 boost::qi 规则的属性必须用括号声明?
- 通过参考或指针声明属性C
- C++属性声明
- 类中变量的属性似乎未声明
- 在可疑的情况下发出叮当警告:函数'foo'可以用属性"noreturn"声明吗?
- 警告:忽略"int scanf(const char*, ...)"的返回值,使用属性 warn_unused_result [-Wunused-result] 声明
- 在具有C++中另一个类类型的类中声明属性
- CodeSynthesis XSD CXX 不解析 XML 文件,表示未声明属性/元素