如果我有一个引用地图的函数:
pair<int,int> myFunc(map<int,char> &myVar){...}
Run Code Online (Sandbox Code Playgroud)
我可以传递一张地图而不需要'&'.
myFunc(someMapitoa);
Run Code Online (Sandbox Code Playgroud)
有什么区别吗?是制作副本然后扔掉?我应该使用'&'吗?
这是我自己的Point类(Point.h):
class Point {
public:
Point(double x, double y, double z);
Point(const Point& orig);
virtual ~Point();
double getX();
double getY();
double getZ();
void writeOut();
private:
double x, y, z;
};
Run Code Online (Sandbox Code Playgroud)
在这里,我创建一个点并将其添加到vector<Point>(main.cpp):
Point* p = new Point(0.1,0.2,0.3);
vector<Point>* points = new vector<Point>;
points->push_back(*p);
//doing stuff
delete points;
Run Code Online (Sandbox Code Playgroud)
我的问题是:矢量制作Point的副本并存储它(所以我也需要delete p;),或者它是否存储之前创建的一个实例?
更新:
我在这里读到push_back"在向量的末尾添加一个新元素,在其当前的最后一个元素之后.val的内容被复制(或移动)到新元素." 但是哪一个?复制还是移动?它是如何确定的?
据我所知std::move(相同static_cast<T&&>)将变量转换为rvalue并分配给左值,因此我想在下面的代码中:
int a = 1;
int b = static_cast<int&&>(a);
Run Code Online (Sandbox Code Playgroud)
b并a具有相同的地址,但在VS中,它打印不同的地址.
int a = 1;
int b = static_cast<int&&>(a);
cout << hex << &a << endl;
cout << hex << &b << endl;
Run Code Online (Sandbox Code Playgroud)
如果此后a仍然指向不同的内存位置,std::move在这种情况下使用有什么好处?
在处理动态内存分配的类中,浅复制基本上会导致程序删除资源两次。在移动操作中,原始指针不再指向资源,那么为什么在移动语义中会出现相同的行为呢?例如:
#include <utility>
#include <cstring>
using namespace std;
class MyString
{
char* cstr;
public:
MyString(const char* arg)
: cstr(new char[strlen(arg)+1])
{
strcpy(cstr, arg);
}
MyString(MyString&&) = default;
MyString& operator=(MyString&&) = default;
MyString(const MyString&) = delete;
MyString& operator=(const MyString&) = delete;
~MyString()
{
delete[] cstr;
}
};
int main()
{
MyString S1{"aaa"};
MyString S2 = move(S1); // error
}
Run Code Online (Sandbox Code Playgroud)
我尝试过 3 个不同的编译器,得到了相同的结果。
有很多文章讨论价值语义与参考语义,也许更多的文章试图解释移动语义.但是,没有人谈论过值语义和移动语义之间的联系.它们是正交概念吗?
注意:这个问题不是关于比较值语义和移动语义,因为很明显这两个概念不是"可比的".这个问题是关于他们是如何联系的,特别是(如@StoryTeller所说),讨论(如何):
移动语义有助于更多地使用值类型.
I have a constructor that looks like this:
Thing::Thing(std::vector<uint8> & data){
m_data = data; // m_data is also a vector<uint8>
// do other stuff
}
Run Code Online (Sandbox Code Playgroud)
However, data holds a pretty large chunk of memory, and instead of copying it, I'd like data to simply give it up to m_data, as the caller will never need it after constructing this object. What's the best way to do this in C++?
TLDR - 如果是这样,请随意将其标记为重复;我会删除问题。然而,我环顾四周后没有找到任何东西。
考虑以下类:
class Base
{
public:
Base(std::string var1);
Base& operator=(Base&& other) noexcept
{
if (this != &other)
var1_ = std::move(other.var1_);
return *this;
}
protected:
std::string var1_;
};
class Child final : public Base
{
public:
Child(std::string var1, std::string var2);
Child& operator=(Child&& other) noexcept
{
if (this != &other)
{
// Take note of HERE for explanation below
Base::operator=(std::move(other));
var2_ = std::move(other.var2_);
}
}
private:
std::string var2_;
};
Run Code Online (Sandbox Code Playgroud)
这里有两个类,Child从Base. Child拥有比 多的成员Base。在 的移动赋值运算符中 …
将 lambda 函数作为参数传递给仅使用(但不存储或转发)lambda 函数的函数的最佳(即性能最高、用途最广)的方法是什么?
选项 1:通过常量引用传递它是要走的路吗?
template <typename F>
void just_invoke_func(const F& func) {
int i = 1;
func(i);
}
Run Code Online (Sandbox Code Playgroud)
选项2:还是将其作为转发引用(通用引用)传递更好?
template <typename F>
void just_invoke_func(F&& func) {
int i = 1;
func(i);
}
Run Code Online (Sandbox Code Playgroud)
后者比前者有什么优势吗?
其中一种解决方案是否有任何危害?
编辑#1:
选项 3:正如Yakk - Adam Nevraumont所指出的,mutablelambdas 不适用于选项 1。那么,另一个采用非常量 l 值引用的版本呢?
template <typename F>
void just_invoke_func(F& func) {
int i = 1;
func(i);
}
Run Code Online (Sandbox Code Playgroud)
问题是:选项 2比选项 3有什么优势吗?
编辑#2:
选项 4:已提出另一种按值获取 lambda 的版本。
template <typename …Run Code Online (Sandbox Code Playgroud) 我已经阅读了几个答案和许多有关移动语义的文章,因此它只是对右值引用的静态转换,这个问题是关于它对堆栈的影响,那么移动后堆栈是否会留下碎片?还是以某种方式重新排列?因为堆栈移动的对象不受堆栈展开的影响。以下代码片段运行良好:
#include <memory>
#include <cassert>
struct A {
int x = 0;
};
struct B {
A a;
};
void SetB(B& b) {
A a1{6}; //pushing into the stack.
A a2{7}; //pushing into the stack.
b.a = std::move(a2);
}
int main()
{
B b;
SetB(b);
assert( b.a.x == 7);
}
Run Code Online (Sandbox Code Playgroud)
a2是在SetB堆栈帧中定义的,但在SetB完成并且控件返回到后仍然可用main。然而; a1不是尽管它更接近main堆栈帧吗?
我一直试图理解 C++ 向量是如何操作的,但我就是不知道它们是如何做这一件事的:它们如何按值传递?
据我所知,向量使用动态数组进行操作,使得它们既快速又易于使用。但是,如果它们使用动态数组,为什么我们可以按值将它们传递给函数呢?传递给函数的值中的指针如何不指向与原始向量的指针相同的位置?
我在网上搜索答案已经有一段时间了,但我能找到的只是“如何按值传递向量”而不是“如何按值传递向量”:(
c++ ×10
c++11 ×5
vector ×3
c++14 ×1
c++17 ×1
inheritance ×1
memory ×1
move ×1
optimization ×1
shallow-copy ×1