当我们有一个希望拥有动态分配项的多个所有者的场景时,将使用shared_ptr.
问题是,我无法想象我们需要多个所有者的任何情况.我可以使用unique_ptr解决我可以成像的每个用例.
有人可以提供一个真实的用例示例,其中代码需要shared_ptr(并且根据需要,我的意思是作为智能指针的最佳选择)?而对于"现实生活",我指的是一些实用和务实的用例,而不是过于抽象和虚构的东西.
在C++ 11之前,您没有非静态成员初始化,也没有构造委派,因此人们经常使用私有帮助函数来帮助初始化以减少代码复制.
这是2018年的好代码吗?
class A {
int a1 = 0;
double a2 = 0.0;
string a3 = "";
unique_ptr<DatabaseHandle> upDBHandle;
void init(){
upDBHandle = open_database(a1, a2, a3);
}
public:
A() { init(); }
explicit A(int i):a1(i) { init(); }
explicit A(double d):a2(d) { init(); }
explicit A(std::string s):a3(std::move(s)) { init(); }
A(int i, double d, std::string s) : a1(i), a2(d), a3(std::move(s)) { init(); }
};
Run Code Online (Sandbox Code Playgroud)
如何改进此代码?
为什么打印20000?代码在继承序列中一直显式调用特定的基础构造函数,但忽略指定的构造函数并使用默认构造函数.
#include <iostream>
struct Car
{
Car() : price(20000) {}
Car(double b) : price(b*1.1) {}
double price;
};
struct Toyota : public virtual Car
{
Toyota(double b) : Car(b) {}
};
struct Prius : public Toyota
{
Prius(double b) : Toyota(b) {}
};
int main(int argc, char** argv)
{
Prius p(30000);
std::cout << p.price << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 目的是std::function什么?据我所知,std::function将函数,仿函数或lambda转换为函数对象.
我不太明白这个的目的...... Lambdas和Functors都已经是函数对象了,我相信它们可以用作排序和转换等算法的谓词.作为旁注,Lambdas实际上是Functors(内部).因此,我唯一能看到std::function的有用的是将常规函数转换为函数对象.
我不太明白为什么我想将常规函数转换为函数对象.如果我想使用一个函数对象,我首先会把它作为一个函子或lambda ...而不是编写一个函数,然后用std :: function转换它,然后将它作为谓词传递给...
我猜测还有更多std::function......乍看之下不太明显的东西.
std::function非常感谢您的解释.
我很难看到如何在C++中安全地分配堆栈数组.
通常人们这样做:
int a[hugeNumber]{0}; //declare,allocate,inti to 0.
Run Code Online (Sandbox Code Playgroud)
由于堆栈溢出,这很容易失败.
我想以某种方式拆分声明和分配,并在try catch中进行分配.
显然这不起作用,因为数组在try之外是不可访问的.
try{
int a[hugeNumber];
}
catch(std::bad_alloc& e)
{
}
//code here can't use a because of scope.
Run Code Online (Sandbox Code Playgroud)
如果你只能通过分离声明和分配以安全的方式分配基于堆的数组,那么生成代码就无法使用基于堆栈的数组,不是吗?
我认为这主要是一种心理锻炼.我一直在考虑它,我没有看到任何地方说明问题.largeNumber在现实中是相对的.实际上,即使是正常的数字也可能导致分配失败,并且因为似乎没有办法安全地分配基于堆栈的数组,我要求显而易见的......"可以在生产代码中使用基于堆栈的数组吗?".我问以防万一有一些我不知道的语法.我真的很感激输入.
不应该在整个继承链中使用复制构造函数吗?
#include<iostream>
using namespace std;
class A
{
public:
A(){ cout <<"1";}
A(const A &obj){ cout <<"2";}
};
class B: virtual public A
{
public:
B(){cout <<"3";}
B(const B & obj){cout<<"4";}
};
class C: virtual public A
{
public:
C(){cout<<"5";}
C(const C & obj){cout <<"6";}
};
class D:B,C
{
public:
D(){cout<<"7";}
D(const D & obj){cout <<"8";}
};
int main()
{
D d1;
D d(d1);
}
Run Code Online (Sandbox Code Playgroud)
输出:
13571358
Run Code Online (Sandbox Code Playgroud)
预期:
13572468
Run Code Online (Sandbox Code Playgroud) 我有一个文件存储在 Artifactory 中。我需要在不下载的情况下获取其校验和。
需要使用BASH。
url="http://$abc/$def/$qwe/file.a?properties"
curl -u "$user":AP"$pass" "$url"
Run Code Online (Sandbox Code Playgroud)
不起作用。我收到错误消息,没有属性。文件存在,有校验和,并且路径正确。
将 MD5 校验和放入 var 并检查命令是否成功会很好。
void f1(unique_ptr<A[]>& upA){
//some work...
//callee can mess up smart pointer many ways for caller
upA.reset();
//some work...
}
void f2(const unique_ptr<A[]>& upA){
//some work...
//compiler stops callee from ruining smart pointer many ways for caller
upA.reset();
//some work...
}
f1(upAArray);
f2(upAArray);
Run Code Online (Sandbox Code Playgroud)
在上面的代码中,调用f1是危险的,因为被调用者可以通过重置智能指针,释放它等来搞乱智能指针等.调用f2是安全的,一切都很好.如果被调用者试图做坏事,编译器会抓住它.这样,当调用堆栈展开并且我们回到调用者时,智能指针就是声音.
重要的是,我不是问最好的智能指针传递方式(我意识到常规原始指针void f3(A*pAArray){}会没问题.我在问f2有什么问题?一般的建议是不要使用const引用unique_ptr作为参数,虽然我知道为什么这不是最优,我不明白为什么它比f1()更糟糕.
简而言之,具体而言,反对f2()的理由是什么?它做坏事吗?它似乎安然无恙(虽然肯定不是最佳的),我不明白它为何如此糟糕.
通过引用返回向量元素是不好的做法吗?
class X{
vector<Y> v;
public:
Y& getRefFromVectorOfY(unsigned int index){
retrun v.at(index);
}
void addToVectorOfY(Y y){
v.push_back(move(y));
}
};
Run Code Online (Sandbox Code Playgroud)
虽然这是有效和干净的,但问题在于它打破了封装.如果v是一个向量,并且是一个类的私有成员,则调用者现在将拥有一个私有向量中的元素的引用,它们不仅可以从中读取,还可以分配给(覆盖).
可以做到这一点
x.getRefFromVectorOfY(0).setNumber(7); //not bad..actually good
Run Code Online (Sandbox Code Playgroud)
要么
x.getRefFromVectorOfY(0) = move(Y2); //very bad!
Run Code Online (Sandbox Code Playgroud)
甚至
Y3 = move(x.getRefFromVectorOfY(0)); //OMG
Run Code Online (Sandbox Code Playgroud)
当然,我们可能会返回一个const,而只允许const操作.
按值返回元素效率较低,因为它是副本.
如果get方法是将元素移出向量以按值返回,则向量将丢失数据完整性,因为它将不再存储已移出的数据(元素将在向量内重置为默认状态...所以......仍然留在向量中,但作为垃圾数据).
我为什么要这样做?观点
如果您遵循零规则,并且您在类中有一个私有向量成员,则需要方便的方法来设置和设置向量.这提出了如何返回值的问题.
ref返回的问题是它破坏了封装,除非它是const ref.
那么,我应该只返回一个const ref强制任何值的设置来使用setVector方法吗?这个问题是有时你存储自定义类型...就像向量中的Y ..你需要访问Y的非const方法.虽然const&保护向量元素不被向量中的重置或覆盖,但它也阻止调用者使用返回的元素非const方法.
所以如果我只返回const&...我做不到
x.getRefFromVectorOfY(0).setNumber(7); //Y has a setNumber method
Run Code Online (Sandbox Code Playgroud)
那将是一个问题.这将是一个问题,因为我不想在X类中重新实现Y的任何方法.这将是另一层间接和大量代码冗余.这反对回报const和一般政策.在许多情况下不实用.
所以我必须基于返回值的常量来覆盖,这是你不能做的.
所以我必须有两个带有diff名称的函数,一个返回const&...而另一个只返回一个&.那感觉很脏.
const Y& getConstRefFromVectorOfY(unsigned int index){
retrun v.at(index);
}
Y& getRefFromVectorOfY(unsigned int index){
retrun v.at(index);
}
Run Code Online (Sandbox Code Playgroud)
编辑
我添加了这个表来总结问题和目标.
我希望X类调用者能够 …
class A{
string m_name;
int m_num;
public:
A(string name="", int number=0) : m_name(name), m_num(number)
{ cout << "ctorA " << m_name << endl; }
virtual ~A(){ cout << "dtorA " << m_name << endl; }
string getName(){ return m_name; }
void setName(const string name){ m_name = name; }
int getNumber(){ return m_num; }
};
class B : public A{
string m_s;
public:
B(string name="", int number=0, string s="")
: A(name, number){ m_s = s; }
string getS(){ return m_s; } …Run Code Online (Sandbox Code Playgroud)