由于我们在C++中移动了语义,所以现在通常这样做
void set_a(A a) { _a = std::move(a); }
Run Code Online (Sandbox Code Playgroud)
原因是,如果a
是左值,则副本将被删除,并且只有一个移动.
但如果a
是左值,会发生什么?似乎将有一个复制结构,然后是一个移动赋值(假设A有一个适当的移动赋值运算符).如果对象具有太多成员变量,则移动分配可能成本很高.
另一方面,如果我们这样做
void set_a(const A& a) { _a = a; }
Run Code Online (Sandbox Code Playgroud)
只有一个副本分配.如果我们传递左值,我们可以说这种方式优于传值的习语吗?
C++ 14将允许创建模板化的变量.通常的例子是变量'pi',可以读取它以获得各种类型的数学常数π的值(3表示int
;可能的最接近的值float
等)
除此之外,我们可以通过将变量包装在模板化的结构或类中来实现此功能,这与类型转换如何混合?我看到一些重叠.
除了pi示例之外,它如何与非const变量一起使用?任何用法示例,以了解如何充分利用此类功能及其目的是什么?
为了便于说明,假设我想实现一个通用的整数比较函数.我可以想到一些定义/调用函数的方法.
(A)功能模板+仿函数
template <class Compare> void compare_int (int a, int b, const std::string& msg, Compare cmp_func)
{
if (cmp_func(a, b)) std::cout << "a is " << msg << " b" << std::endl;
else std::cout << "a is not " << msg << " b" << std::endl;
}
struct MyFunctor_LT {
bool operator() (int a, int b) {
return a<b;
}
};
Run Code Online (Sandbox Code Playgroud)
这将是对此函数的几个调用:
MyFunctor_LT mflt;
MyFunctor_GT mfgt; //not necessary to show the implementation
compare_int (3, 5, "less than", mflt);
compare_int (3, …
Run Code Online (Sandbox Code Playgroud) 如果我没错,我认为const引用和rvalue引用都可以绑定到rvalue.返回前者的函数和返回后者的函数之间是否存在实际差异?
编辑.我无法修改前者,但为什么我有兴趣修改右值?是否有意义?
似乎每一次你添加一个新的元素到std::vector
,如果没有空元素,分配元素的数量加倍(至少在GCC 4.9).我认为这样做是为了实现摊销的恒定时间复杂度.
例如,运行此代码后:
v.push_back (1);
v.push_back (2);
v.push_back (3);
v.push_back (4);
v.push_back (5);
v.shrink_to_fit(); // capacity is 5 now
v.push_back (6);
std::cout << v.capacity () << std::endl;
Run Code Online (Sandbox Code Playgroud)
输出为10.
在内存受限系统中,有没有办法防止这种行为,即使它是以性能损失为代价的?
此外,是否可以指出它应该只分配固定数量的元素而不是加倍?
我知道我可以std::vector::reserve()
在添加新元素之前调用,但在我的情况下看起来一团糟......调用std::vector::shrink_to_fit()
是另一种方法,但也不方便.
由于STL容器要求所有内容都是可复制和可分配的,因此在处理不可复制对象时,首选的习惯是什么?
我可以想到两种不同的方法:
存储(智能)指针而不是STL容器中的对象.
摆脱STL容器并实现我自己的列表(例如,每个对象必须包含指向下一个对象的指针).
第二种方法的主要缺点是析构函数的实现("下一个"对象应该以递归方式在当前对象之前销毁吗?)
我知道在班级中拥有公共字段被认为是一个坏主意。但是,当您的类包含大量分层数据结构和字段时,最好的方法是什么?例如:
class A {B d1; C d2; D d3;}
class B {E d4; F d5;}
class E {G d6; int d7;}
Run Code Online (Sandbox Code Playgroud)
在C中,访问这样的数据结构非常容易,例如ptr_to_A->d1.d4.d7等等...但是当我们使用setter/getters时,方法是什么?
在 C++ 中使用 setter 和 getter 时,像 A.get_d1().get_d4().get_d7() 这样的表达式似乎不太方便,并且它们会强制返回引用。由于某些结构非常大,因此按值返回似乎是一个糟糕的主意。
在这些情况下您使用哪种方法或编码风格?也许摆脱 setter/getter 并将这些字段公开?
这段代码在C++中有效吗?
class MyClass
{
public:
Class2 array [100];
Myclass (const Myclass& other) : array (other.array) {}
};
Run Code Online (Sandbox Code Playgroud)
如果不是,那么获得相同结果的最佳方法是什么?
假设我有一个STL向量,其元素是指向其他类的原始指针。显然,向量的析构函数不会释放这些指针拥有的内存。是否有可能实现释放该内存的自定义析构函数?
在C++中实现指向不同类型的指针列表的最佳方法是什么?
我想做这样的事情:
enum MyType {...};
typedef std::pair<MyType, void*> Ptr;
std::vector <Ptr> list;
Run Code Online (Sandbox Code Playgroud)
然后,只要我需要访问列表中的一个对象,就进行合适的静态类型转换.
另一种方法是为每种对象类型设置不同的向量:
std::vector<ClassA*> list_a;
std::vector<ClassB*> list_b;
...
Run Code Online (Sandbox Code Playgroud)
问题是我需要实现一个图形,其中并非所有顶点都具有相同的类型.
编辑.表现至关重要.代码越有效越好.
我已经读过下面的代码在C++ 11中有效:
int && a = 3;
a = 4;
Run Code Online (Sandbox Code Playgroud)
是否应该在存储数字文字3的内存地址中写入4?也许一些编译器优化可以防止这种情况发生,但它应该这样做吗?
考虑这个Java代码片段:
Vertex a = graph.addVertex(null);
Vertex b = graph.addVertex(null);
Run Code Online (Sandbox Code Playgroud)
是否有可能在C++中做同样的事情?C++中唯一的AFAIK选项是:
Vertex& a = graph.addVertex(NULL);
Run Code Online (Sandbox Code Playgroud)
或许这个:
typedef Vertex& Vertexref;
Vertexref a = graph.addVertex(NULL);
Run Code Online (Sandbox Code Playgroud)
当然,返回对象的副本也是可能的.
但Java语法对我来说似乎更直接.是否有可能在C++中使用它?