如果我有一个需要使用a的函数shared_ptr,那么传递它的引用会不会更有效(所以为了避免复制shared_ptr对象)?有哪些可能的不良副作用?我设想了两种可能的情况:
1)在函数内部,复制由参数组成,如
ClassA::take_copy_of_sp(boost::shared_ptr<foo> &sp)
{
...
m_sp_member=sp; //This will copy the object, incrementing refcount
...
}
Run Code Online (Sandbox Code Playgroud)
2)在函数内部仅使用参数,例如
Class::only_work_with_sp(boost::shared_ptr<foo> &sp) //Again, no copy here
{
...
sp->do_something();
...
}
Run Code Online (Sandbox Code Playgroud)
我无法在两种情况下都看到传递boost::shared_ptr<foo>by值而不是引用的充分理由.按值传递只会"暂时"增加由于复制而引用的引用计数,然后在退出函数范围时减少它.我忽略了什么吗?
只是为了澄清,在阅读了几个答案之后:我完全赞同过早优化的问题,而且我总是试着先在热点上进行首次剖析.如果你知道我的意思,我的问题更多来自纯粹的技术代码观点.
考虑用来解释一下这个典型的例子并不与前向声明做:
//in Handle.h file
class Body;
class Handle
{
public:
Handle();
~Handle() {delete impl_;}
//....
private:
Body *impl_;
};
//---------------------------------------
//in Handle.cpp file
#include "Handle.h"
class Body
{
//Non-trivial destructor here
public:
~Body () {//Do a lot of things...}
};
Handle::Handle () : impl_(new Body) {}
//---------------------------------------
//in Handle_user.cpp client code:
#include "Handle.h"
//... in some function...
{
Handle handleObj;
//Do smtg with handleObj...
//handleObj now reaches end-of-life, and BUM: Undefined behaviour
}
Run Code Online (Sandbox Code Playgroud)
我从标准中了解到这个案例正朝向UB,因为Body的析构函数是非常重要的.我想要了解的是这个的根本原因.
我的意思是,问题似乎是由Handle的dtor内联的事实"触发",因此编译器执行类似下面的"内联扩展"(这里几乎是伪代码).
inline Handle::~Handle()
{ …Run Code Online (Sandbox Code Playgroud) c++ destructor memory-management forward-declaration delete-operator
有人可以清楚地解释我们从Solaris中的prstat获得的SIZE和RSS值的含义吗?
我写了一个测试C++应用程序,它分配内存new[],填充它并释放它delete[].
据我所知,SIZE值应该与进程"保留"了多少虚拟内存有关,即内存"malloced"或"newed".
除非我真的使用它(填充一些值),否则该内存不会在RSS值中总结.但即使我释放内存,RSS也不会下降.
我不明白我能正确分配给这两个值的语义.
我试图用c ++ 11统一初始化来解决一些极端情况,我无法弄清楚为什么会这样:
struct Base
{
int x,y,z;
};
struct Derived : Base
{
};
static_assert (std::is_trivial<Base>::value, "Base must be trivial");
static_assert (std::is_trivial<Derived>::value, "Derived must be trivial");
Base b{1, 2, 3}; // 1) This compiles fine
Derived d{10, 20, 30}; // 2) This fails
Run Code Online (Sandbox Code Playgroud)
标记为2的行失败,并带有"无用于初始化Derived的匹配构造函数"消息clang 3.1和g++ 4.7.
我无法理解为什么,在Derived的情况下,它试图调用构造函数而不执行(我不知道如何调用它,可能是聚合初始化?),就像第1行的情况一样.
以下推理中的某些内容是错误的?:
A)微不足道的保证它可以静态初始化
B)要静态初始化没有代码必须在运行时执行,因此不需要构造函数调用
A+B=>为什么它试图在一个它知道微不足道的类型上调用构造函数?
我很困惑....
c++ inheritance uniform-initialization c++11 list-initialization
我有以下代码:
struct simple
{
simple (int a1, int a2) : member1(a1), member2(a2) {}
int member1;
int member2;
};
std::ofstream &operator << (std::ofstream &f, const simple &obj)
{
f<<obj.member1<<", "<<obj.member2;
return f;
}
int main(int argc, const char *argv[])
{
std::ofstream f("streamout.txt");
simple s(7,5);
f << s; //#1 This works
f << "label: " << s; //#2 This fails
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我试图理解为什么#1工作,而在尝试使用重载运算符连接时出现问题,因为#2失败并出现以下错误(MacOSX上的gcc 4.5.3):
错误:无法将'std :: basic_ostream'左值绑定到'std :: basic_ostream &&'/ GCC-FACTORY/4.5/INSTALL/lib/gcc/x86_64-apple-darwin10.5.0/4.5.3/../../. ./../include/c++/4.5.3/ostream:579:5:错误:初始化'std :: basic_ostream <_CharT,_Traits>&std :: operator <<的参数1(std :: basic_ostream <_CharT, …
所以我在STL的关联容器中寻找对异构查找的支持(自C++ 14以来),并对我们可以做什么和不应该做什么感到困惑.
以下代码段
#include <algorithm>
#include <iostream>
#include <set>
struct partial_compare : std::less<>
{
//"full" key_type comparison done by std::less
using less<>::operator();
//"sequence-partitioning" comparison: only check pair's first member
bool operator ()(std::pair<int, int> const &lhs, int rhs) const
{
return lhs.first < rhs;
}
bool operator ()(int lhs, std::pair<int, int> const &rhs) const
{
return lhs < rhs.first;
}
};
int main()
{
//Using std::set's lookup
{
std::cout << "std::set's equal_range:\n";
std::set <std::pair<int, int>, partial_compare> s{{1,0},{1,1},{1,2},{1,3},{2,0}};
auto r = s.equal_range …Run Code Online (Sandbox Code Playgroud) 我很想知道在以下两种方式指定库(共享和静态)与gcc/g ++之间是否存在任何实质性差异(CC可以是g ++或gcc)
CC -o output_executable /path/to/my/libstatic.a /path/to/my/libshared.so source1.cpp source2.cpp ... sourceN.cpp
Run Code Online (Sandbox Code Playgroud)
VS
CC -o output_executable -L/path/to/my/libs -lstatic -lshared source1.cpp source2.cpp ... sourceN.cpp
Run Code Online (Sandbox Code Playgroud)
我只能看到一个主要的区别是,直接传递完全指定的库名称将有助于更好地控制选择静态或动态版本,但我怀疑还有其他事情会对可执行文件的构建方式产生副作用或我会在运行时表现,对吗?
安德烈.
正如我理解标准一样,一个简单的析构函数是一个隐式声明的析构函数,它的类只有基本和非静态成员和简单的析构函数.鉴于此定义的递归性,在我看来,唯一的"递归停止"条件是找到具有非隐式声明的析构函数的基础或非静态成员(即用户声明).如果这是正确的,那应该意味着一个简单的析构函数是"不必做任何事情",因此它将被声明(隐式)但没有定义.用另一种方式说:根据标准定义,隐含定义的析构函数(即"它做某事")是不是很简单?
对不起那种愚蠢的问题,但我想在脑海中澄清一些事情......
阅读有关ACCU过载的有趣文章#115:"恶魔可能会飞出你的鼻子"我发现作者说:
在序列点之间,不允许对涉及变量的状态做出任何假设.这也意味着在C中,与大多数其他语言不同,以下表达式会导致未定义的行为
v [i] = i ++;
因为赋值运算符不代表C中的序列点
有人可以解释一下UB的详细推理是什么吗?我认为在两个序列点之间对同一个变量进行多次写操作是个问题,除了v [i]别名的可能性之外我在这里看不到...
c++ ×6
destructor ×2
boost ×1
c ×1
c++11 ×1
c++14 ×1
g++ ×1
gcc ×1
inheritance ×1
libraries ×1
linker ×1
ofstream ×1
shared-ptr ×1
solaris ×1
stl ×1