与C++ 11中的普通指针相比,智能指针的开销是多少?换句话说,如果我使用智能指针,我的代码会变慢吗?如果是这样,速度会慢多少?
具体来说,我问的是C++ 11 std::shared_ptr和std::unique_ptr.
显然,推下堆栈的东西会变得更大(至少我认为是这样),因为智能指针也需要存储其内部状态(引用计数等),问题是,这是多少影响我的表现,如果有的话?
例如,我从函数而不是普通指针返回一个智能指针:
std::shared_ptr<const Value> getValue();
// versus
const Value *getValue();
Run Code Online (Sandbox Code Playgroud)
或者,例如,当我的一个函数接受智能指针作为参数而不是普通指针时:
void setValue(std::shared_ptr<const Value> val);
// versus
void setValue(const Value *val);
Run Code Online (Sandbox Code Playgroud) 来自http://en.cppreference.com/w/cpp/string/byte/memcpy:
如果对象不是TriviallyCopyable(例如标量,数组,C兼容结构),则行为未定义.
在我的工作中,我们使用std::memcpy了很长时间来按比例交换不是TriviallyCopyable的对象:
void swapMemory(Entity* ePtr1, Entity* ePtr2)
{
static const int size = sizeof(Entity);
char swapBuffer[size];
memcpy(swapBuffer, ePtr1, size);
memcpy(ePtr1, ePtr2, size);
memcpy(ePtr2, swapBuffer, size);
}
Run Code Online (Sandbox Code Playgroud)
从来没有任何问题.
我理解滥用std::memcpy非TriviallyCopyable对象并导致下游的未定义行为是微不足道的.但是,我的问题是:
std::memcpy当与非TriviallyCopyable对象一起使用时,为什么它本身的行为是未定义的?为什么标准认为有必要指定?
UPDATE
http://en.cppreference.com/w/cpp/string/byte/memcpy的内容已经过修改,以回应这篇文章和帖子的答案.目前的描述说:
如果对象不是TriviallyCopyable(例如标量,数组,C兼容结构),则行为是未定义的,除非程序不依赖于目标对象(不运行
memcpy)的析构函数的效果和生命周期目标对象(已结束,但未开始memcpy)由其他一些方法启动,例如placement-new.
PS
@Cubbi的评论:
@RSahu如果有东西保证UB下游,它会使整个程序不确定.但我同意在这种情况下似乎可以绕过UB并相应地修改cppreference.
我有兴趣知道是否有任何可行的方法来连续存储多态对象数组,这样virtual可以合法地调用公共基础上的方法(并将调度到子类中正确的重写方法).
例如,考虑以下类:
struct B {
int common;
int getCommon() { return common; }
virtual int getVirtual() const = 0;
}
struct D1 : B {
virtual int getVirtual final const { return 5 };
}
struct D2 : B {
int d2int;
virtual int getVirtual final const { return d2int };
}
Run Code Online (Sandbox Code Playgroud)
我想分配一个连续的D1和D2对象数组,并将它们视为B对象,包括调用getVirtual()哪些将根据对象类型委托给适当的方法.从概念上讲,这似乎是可能的:每个对象通常通过嵌入的vtable指针知道它的类型,因此您可以想象,将n个对象存储在数组中,并使用放置和初始化对象,并将指针转换为.不过,我很确定演员不合法.n * max(sizeof(D1), sizeof(D2)) unsigned charnewdeleteunsigned charB*
人们还可以想象创建一个联盟,如:
union Both { …Run Code Online (Sandbox Code Playgroud) 我正在努力尝试使用枚举和大量的宏观魔法来实现vtable的替代品,这种魔法真的开始让我的大脑混乱.我开始认为我没有走正确的道路,因为代码变得更加丑陋和丑陋,并且无论如何都不适合生产.
如何使用最少量的重定向/操作实现以下代码的模式?
它必须在标准的c ++中完成,最多17个.
class A{
virtual void Update() = 0; // A is so pure *¬*
};
class B: public A
{
override void Update() final
{
// DO B STUFF
}
}
class C: public A
{
override void Update() final
{
// DO C STUFF
}
}
// class...
int main()
{
std::vector<A*> vecA{};
// Insert instances of B, C, ..., into vecA
for(auto a: vecA) // This for will be inside a main loop
a->Update(); // …Run Code Online (Sandbox Code Playgroud) 经验教训,在做基准测试时总是使用优化...
我决定将其std::unique_ptr视为我的计划的替代方案.关于为什么不重要的原因.
使用编译器优化后,它们似乎需要等量的时间.
我是如何测试的:
time_t current_time;
time(¤t_time);
srand((int)current_time);
//int* p0 = new int[NUM_TESTS];
//int* p1 = new int[NUM_TESTS];
std::unique_ptr<int[]> u_p0{ new int[NUM_TESTS] };
std::unique_ptr<int[]> u_p1{ new int[NUM_TESTS] };
for (unsigned i = 0; i < NUM_TESTS; ++i){
u_p0[i] = rand(); // Use p0 and p1 for the standard ptr test
u_p1[i] = rand();
}
int result;
auto start = std::chrono::steady_clock::now();
for (unsigned index = 0; index < NUM_TESTS; ++index){
result = u_p0[index] + u_p1[index]; // Use p0 and …Run Code Online (Sandbox Code Playgroud) c++ ×5
c++11 ×3
performance ×2
dispatch ×1
enums ×1
memcpy ×1
pointers ×1
polymorphism ×1
unique-ptr ×1