我有一些代码让我感到困惑.特别是,当我尝试将某些内容添加到列表作为初始化列表时 - 它一直有效,直到我添加析构函数 - 然后它开始尝试查找复制构造函数.
这似乎并不是完全一致的行为.拿这个最小的例子:
#include <list>
int main()
{
class MemberType
{
public:
MemberType() {}
MemberType(MemberType&& copy) { }
};
struct ListItemType
{
MemberType x;
~ListItemType() {}
};
std::list<ListItemType> myList;
myList.push_back({MemberType()});
return 0;
}
Run Code Online (Sandbox Code Playgroud)
这无法在GCC和VS2015中编译,因为push_back尝试访问ListItemType复制构造函数:
main()::ListItemType::ListItemType(const main()::ListItemType&)
Run Code Online (Sandbox Code Playgroud)
(根据我的理解).这似乎是有道理的,因为列表push_back将复制(因为没有移动构造函数),除非这不是行为,如果您删除析构函数.注释掉析构函数,编译按预期成功.
也就是说,即使使用析构函数,以下工作也很好 - 不需要复制或移动构造函数来满足它.这对我来说似乎是一样的行为.
ListItemType foo = { MemberType() };
Run Code Online (Sandbox Code Playgroud)
最后,如果删除或注释掉移动构造函数MemberType- 编译再次成功 - 意味着以下将编译.
#include <list>
int main()
{
class MemberType
{
public:
MemberType() {}
};
struct ListItemType
{ …Run Code Online (Sandbox Code Playgroud) 请考虑以下代码:
#include <iostream>
struct Data
{
int x, y;
};
Data fill(Data& data)
{
data.x=3;
data.y=6;
return data;
}
int main()
{
Data d=fill(d);
std::cout << "x=" << d.x << ", y=" << d.y << "\n";
}
Run Code Online (Sandbox Code Playgroud)
这d是从返回值复制初始化的fill(),但在返回结果之前fill()写入d自身.我关心的是d在初始化之前非常简单地使用它,并且在一些(所有?)情况下使用未初始化的变量会导致不确定的行为.
那么这段代码是有效的,还是有未定义的行为?如果它有效,一旦Data停止POD或在其他情况下,行为是否会变得不确定?
我正在编写一个模板类,它在内部管理给定类型的数组.像这样:
template<typename T>
class Example {
// ...
private:
T* objects; // allocated in c'tor (array), deleted in d'tor
// ...
};
Run Code Online (Sandbox Code Playgroud)
我想知道objects当我删除它时,C++是否会调用每个对象的析构函数delete[] objects;.
我需要知道这一点,因为我的类中的对象始终不包含合理的值,因此不应该在不执行时调用析构函数.
此外,我想知道,如果我宣布一个固定大小的数组像析构函数将被称为T objects[100]作为的一部分Example<T>.
我的问题是,假设我们有两个A和B类.我想在A类中有一个B的对象.
我应该用,
class A
{
public:
A();
~A();
B* b;
};
Run Code Online (Sandbox Code Playgroud)
要么
class A
{
public:
A();
~A();
B b;
};
Run Code Online (Sandbox Code Playgroud)
据我所知,在第一个场景中,我可以*b使用new运算符初始化对象,对于第二个场景,b如果我不想使用默认构造函数,我可以使用初始化列表进行初始化class B.哪个更方便使用?
是否有任何一点实现移动构造函数并为仅包含基本类型的结构或类移动赋值运算符?例如,
struct Foo
{
float x;
float y;
float z;
/// ... ctor, copy ctor, assignment overload, etc...
};
Run Code Online (Sandbox Code Playgroud)
我可以看到,如果我有更复杂的东西,比如:
struct Bar
{
float x,y,z;
std::string Name;
};
Run Code Online (Sandbox Code Playgroud)
我宁愿移动而Name不是复制它,移动ctor会有意义.然而,"移动"浮动并不(语义上)对我有意义.
思考?
在一个probject中我使用了类似于以下的代码:
class C {
public:
C() {}
C(const C&) = delete;
};
C f() {
return C();
}
int main() {
f();
}
Run Code Online (Sandbox Code Playgroud)
在我之前使用的每个Visual C++编译器中(直到2013年),这从来都不是问题.但是当我尝试使用新的Visual C++ 2015编译器编译它时,我收到以下错误:
1>c:\devel\c++11\playground\main.cpp(10): error C2280: 'C::C(const C &)': attempting to reference a deleted function
1> c:\devel\c++11\playground\main.cpp(6): note: see declaration of 'C::C'
Run Code Online (Sandbox Code Playgroud)
我不确定它为什么以前有效,但我认为由于返回值优化,默认构造函数被调用而不是复制构造函数.
我使用的代码甚至是合法的C++吗?如果没有,那么在不需要我的类的复制构造函数的情况下实现此代码的正确方法是C什么?我当然可以使用移动构造函数但是我认为代码在C++ 11之前从来就不是有效的C++?
考虑这些类:
#include <iostream>
#include <string>
class A
{
std::string test;
public:
A (std::string t) : test(std::move(t)) {}
A (const A & other) { *this = other; }
A (A && other) { *this = std::move(other); }
A & operator = (const A & other)
{
std::cerr<<"copying A"<<std::endl;
test = other.test;
return *this;
}
A & operator = (A && other)
{
std::cerr<<"move A"<<std::endl;
test = other.test;
return *this;
}
};
class B
{
A a;
public:
B (A && a) …Run Code Online (Sandbox Code Playgroud) 我有程序,实现人民和他的公司的数据库.我已经创建了指向类成员的动态数组指针而不是类成员的动态数组,因此使用它可以更快地进行复制.
我有版本,但valgrind在析构函数中显示不匹配删除(删除db)
CCompany** db;
~CCompanyIndex ( void )
{
for(unsigned i=0;i<len;i++)
{
/*cout<<"dealloc:"<<db[i]<<endl;*/
delete db[i];
}
delete db;
}
CCompanyIndex ( void )
{
max=1000;
len=0;
db=new CCompany*[max];
}
Run Code Online (Sandbox Code Playgroud)
我也用来添加
CCompany* newIt=new CCompany(oName,oAddr,cName,cAddr);
Run Code Online (Sandbox Code Playgroud)
所以我尝试了以下我认为正确的代码
~CCompanyIndex ( void )
{
delete [] db;
}
Run Code Online (Sandbox Code Playgroud)
但是,通过添加方法分配的所有内存都不会被释放.
说一堂课
class Piece {} ;
如果我是对的,应该相当于:
class Piece {
//C++ 03
Piece (); //default constructor
Piece( const Piece&); //copy constructor
Piece& operator=(const Piece&); //copy assignment operator
~Piece(); //destructor
//Since C++ 11
Piece(Piece&&); //move constructor
Piece& operator=(Piece&&); //move assignment operator
};
Run Code Online (Sandbox Code Playgroud)
那么我能说些什么呢?
一个)
class Pawn{
~Pawn() {}// Only destructor
};
Run Code Online (Sandbox Code Playgroud)
b)
class Bishop{
Bishop(Bishop&& ) {}// Only move constructor
};
Run Code Online (Sandbox Code Playgroud)
C)
class Knight{
Knight(Knight&&, int =0) {} // move constructor, when no second arg present
};
Run Code Online (Sandbox Code Playgroud)
d)
class Rook {
Rook(const …Run Code Online (Sandbox Code Playgroud) 我有这个下面的程序,我通过引用函数传递一个向量myFunc,在这个函数里面,我向向量添加了一些元素.
我没有释放用new创建对象,现在忽略由此引起的内存泄漏.
后myFunc()执行完成我打印变量构造函数和析构函数知道多少次的构造函数和析构函数是如何调用.
输出是:
Before Exiting 5 7
Run Code Online (Sandbox Code Playgroud)
我创建了5个对象,以便ctor为5.但为什么dtor 7呢?额外的两个计数从何而来?我错过了什么吗?
#include
#include
using namespace std;
static int ctor = 0;
static int dtor = 0;
class MyClass
{
public:
MyClass(int n)
{
i = n;
ctor++;
// cout << "Myclass ctor " << ctor << endl;
}
~MyClass()
{
dtor++;
// cout << "Myclass dtor" << dtor << endl;
}
private:
int i;
};
void myFunc(vector<MyClass> &m);
void myFunc(vector<MyClass> &m) …Run Code Online (Sandbox Code Playgroud)