关于智能指针和新的C++ 11/14功能,我想知道具有这些功能的类的最佳实践返回值和函数参数类型是什么:
一个工厂函数(在类之外),它创建对象并将它们返回给类的用户.(例如,打开文档并返回可用于访问内容的对象.)
实用程序函数接受来自工厂函数的对象,使用它们,但不取得所有权.(例如,计算文档中单词数量的函数.)
在返回对象后保持对对象引用的函数(如获取对象副本的UI组件,以便它可以根据需要在屏幕上绘制内容.)
工厂功能的最佳返回类型是什么?
delete正确地使用它,这是有问题的.unique_ptr<>则用户无法共享它.shared_ptr<>那么我将不得不传遍各地的shared_ptr<>类型?这就是我现在正在做的事情,它导致了问题,因为我正在获取循环引用,防止对象被自动销毁.效用函数的最佳参数类型是什么?
const参数来说明该函数不会修改对象,而不会破坏智能指针的兼容性?保持对象引用的函数的最佳参数类型是什么?
shared_ptr<>是这里唯一的选择,这可能意味着工厂类必须返回一个shared_ptr<>,对吗?这里有一些代码可以编译并希望说明要点.
#include <iostream>
#include <memory>
struct Document {
std::string content;
};
struct UI {
std::shared_ptr<Document> doc;
// This function is not copying the object, but holding a
// reference to it to make sure it doesn't get destroyed.
void setDocument(std::shared_ptr<Document> newDoc) {
this->doc = newDoc;
}
void redraw() {
// …Run Code Online (Sandbox Code Playgroud) 我来自C背景,正在学习Python.缺乏明确的类型安全性是令人不安的,但我已经习惯了.面对动态语言的所有优点,缺乏内置的基于合同的编程(纯抽象类,接口)是习惯的东西.
然而,无法请求const-cortectness让我发疯!为什么Python中没有常量?为什么不鼓励类级常量?
让我们在一个示例中展示它,其中我们有一个包含主数据的 Data 类、某种指向主数据的索引,并且我们还需要公开索引const的版本。
class Data
{
public:
const std::vector<int>& getPrimaryData() const { return this->primaryData; }
const std::vector<int*>& getIndex() const { return this->index; }
private:
std::vector<int> primaryData;
std::vector<int*> index;
};
Run Code Online (Sandbox Code Playgroud)
这是错误的,因为用户可以轻松修改数据:
const Data& data = something.getData();
const std::vector<int*>& index = data.getIndex();
*index[0] = 5; // oups we are modifying data of const object, this is wrong
Run Code Online (Sandbox Code Playgroud)
原因是 Data::getIndex 应返回的正确类型是:
const std::vector<const int*>&
Run Code Online (Sandbox Code Playgroud)
但是您可以猜测当您尝试以“仅将非常量变体转换为常量变体”的方式编写方法时会发生什么:
// compiler error, can't convert std::vector<int*> to std::vector<const int*> these are unrelated types.
const std::vector<const int*>& …Run Code Online (Sandbox Code Playgroud) 它是合法的指针到非const转换为指针到常量.
那么为什么将指向非const的指针转换为指向const的指针是不合法的呢?
例如,为什么以下代码是非法的:
char *s1 = 0;
const char *s2 = s1; // OK...
char *a[MAX]; // aka char **
const char **ps = a; // error!
Run Code Online (Sandbox Code Playgroud) 所以我有一些相当广泛的功能代码,主要数据类型是不可变的结构/类.通过制作成员变量和任何方法const,我一直在声明不变性的方式是"几乎不可变的".
struct RockSolid {
const float x;
const float y;
float MakeHarderConcrete() const { return x + y; }
}
Run Code Online (Sandbox Code Playgroud)
这实际上是C++中"我们应该这样做"的方式吗?或者,还有更好的方法?
c++ functional-programming const-correctness immutability c++11
考虑以下代码:
#include <iostream>
void f(int const& a, int& b)
{
b = a+1;
}
int main() {
int c=2;
f(c,c);
std::cout << c << std::endl;
}
Run Code Online (Sandbox Code Playgroud)
f采用两个引用参数:int const& a 和int& b。因此,f不应该修改a,但它可以修改b,并且确实可以。main,我传递了相同的变量,同时引用了bya和 by b。作为f修改b,它也修改a,它应该不应该此代码在没有任何警告的情况下编译并打印3。如果我们单独跟踪每个变量,它看起来像常量-正确性推崇:c是非const,因此它是完全没有把它作为一个const参考的a,也可作为一个非const REF为b,和体内f我们modify b,这是非常量,而不是 touching …
c++ const-correctness pass-by-reference pass-by-const-reference
我有一个函数float**作为参数接收,我试图改变它采取const float**.
编译器(g++)不喜欢它并发出:
invalid conversion from ‘float**’ to ‘const float**’
这对我没有意义,我知道(并且已经验证)我可以传递char*给一个需要的函数,const char*为什么不用const float**?
我知道关于const正确性的问题很少,其中声明函数的声明及其定义不需要同意值参数.这是因为值参数的常量仅在函数内部很重要.这可以:
// header
int func(int i);
// cpp
int func(const int i) {
return i;
}
Run Code Online (Sandbox Code Playgroud)
这样做真的是最好的做法吗?因为我从未见过有人这样做过.我已经在其他地方看过这个引用(不确定来源),这已被讨论过:
"事实上,对于编译器,无论是否在值参数前面包含此const,函数签名都是相同的."
"避免在函数声明中使用const值传递参数.如果不修改参数const,则仍然将参数const置于同一函数的定义中."
第二段说不要将const放在声明中.我假设这是因为值参数的常量作为接口定义的一部分是没有意义的.这是一个实现细节.
根据这个建议,是否也建议指针参数的指针值?(它对参考参数没有意义,因为您无法重新分配参考.)
// header
int func1(int* i);
int func2(int* i);
// cpp
int func1(int* i) {
int x = 0;
*i = 3; // compiles without error
i = &x; // compiles without error
return *i;
}
int func2(int* const i) {
int x = 0;
*i = 3; // compiles without error
i = &x; // compile error
return *i; …Run Code Online (Sandbox Code Playgroud) 指针可以声明为指向可变(非常量)数据或指向常量数据的指针.
可以将指针定义为指向函数.
我的同事和我正在讨论使用带有指针的"const",并且出现了关于使用const函数指针的问题.
以下是一些问题:
typedef void (*Function_Pointer)(void); // Pointer to void function returning void.
void function_a(Function_Pointer p_func); // Example 1.
void function_b(const Function_Pointer p_func); // Example 2.
void function_c(Function_Pointer const p_func); // Example 3.
void function_d(const Function_Pointer const p_func); // Example 4.
Run Code Online (Sandbox Code Playgroud)
上述声明是将函数指针视为指向内部类型的指针的示例.
数据,变量或存储器指针允许上述组合.
所以问题是:函数指针是否具有相同的组合以及指向const函数的指针(例如示例2)是什么意思?
在接口中定义函数时:
virtual void ModifyPreComputedCoeffs ( std::vector < IndexCoeffPair_t > & model_ ) = 0;
Run Code Online (Sandbox Code Playgroud)
我们想要指定不应该在push_back等意义上改变向量model_操作不应该对向量进行操作,但是可以更改model_中的IndexCoeffPair_t结构对象.我们该如何指定?
virtual void ModifyPreComputedCoeffs ( const std::vector < IndexCoeffPair_t > & model_ ) = 0;
Run Code Online (Sandbox Code Playgroud)
我觉得不行.