我试图在我的结构中包含一个向量.
这是我的结构:
struct Region
{
bool hasPoly;
long size1;
long size2;
long size3;
long size4;
long size5;
long size6;
//Mesh* meshRef; // the mesh with the polygons for this region
long meshRef;
std::vector<int> PVS;
} typedef Region;
Run Code Online (Sandbox Code Playgroud)
此声明中的向量是有效还是更有意义地指向向量.在指向矢量的指针的情况下,我是否需要分配新的矢量.我怎么做到这一点?
谢谢!
编辑:问题是它最终导致错误指向xmemory.h,这是MSVC++平台附带的文件.
void construct(pointer _Ptr, _Ty&& _Val)
{ // construct object at _Ptr with value _Val
::new ((void _FARQ *)_Ptr) _Ty(_STD forward<_Ty>(_Val)); // this is the line
}
Run Code Online (Sandbox Code Playgroud)
有趣的是,如果我将它分配到结构之外并且只是在我使用的函数中,它就不会发生.有任何想法吗?
重新分配变量时,不会调用析构函数:
Object foo = Object(a,b);
foo = Object(c,d);
Run Code Online (Sandbox Code Playgroud)
因此,析构函数只会在Object(c,d)范围的末尾被调用,这显然会导致问题.现在,在这种特殊情况下,它并没有太多困扰我:它足以声明2个不同的对象:
Object foo1 = Object(a,b);
Object foo2 = Object(c,d);
Run Code Online (Sandbox Code Playgroud)
这样,两个对象的析构函数将在最后被调用.
但是,有一种情况我必须重新分配变量,即在对象构造函数中,例如:
SuperObject(Point point1, Point point2) : delay_object_(DelayObject(0)) {
double distance = distance(point1, point2);
double delay = distance / speed;
delay_object_ = DelayObject(delay);
}
Run Code Online (Sandbox Code Playgroud)
事实上,DelayObject参数不容易计算(在这个例子中我也省略了一些其他段落),我想避免在初始化列表中这样做.
我以为我可以通过将对象放在堆中并显式调用析构函数来强制删除:
SuperObject(Point point1, Point point2) : p_delay_object_(new DelayObject(0)) {
double distance = distance(point1, point2);
double delay = distance / speed;
delete p_delay_object_;
p_delay_object_ = new DelayObject(delay);
}
Run Code Online (Sandbox Code Playgroud)
但这对我来说真的很难看,因为我更喜欢在严格必要的时候使用动态分配.我错过了什么吗?
干杯!
背景: 我有一个复杂的类,有很多变量.我有一个声音和测试的复制构造函数:
Applepie::Applepie( const Applepie ©) :
m_crust(copy.m_crust),
m_filling(copy.m_filling)
{
}
Run Code Online (Sandbox Code Playgroud)
在初始化列表中调用的一些成员变量复制构造函数执行分配.
问题:
我需要创建operator=.我可以简单地执行以下操作,而不是使用赋值而不是初始化列表复制现有的构造函数,释放正在被替换的内存等等,
Applepie& Applepie::operator=( const Applepie ©)
{
if( this != ©)
{
this->~Applepie(); // release own object
new(this) Applepie(copy); // placement new copy constructor
}
return *this;
}
Run Code Online (Sandbox Code Playgroud)
换句话说,是毁灭自我后跟一个放置新的复制构造函数在语义上与operator =?
这似乎有可能大大减少重复代码并确认每个变量都已正确初始化,但代价是在分配期间可能会略微降低效率.我错过了一些更加模糊的东西吗?
理由: 我的实际班级有大约30个变量.我担心我的复制构造函数和我的赋值操作符都必须复制所有三十个,并且代码可能会发散,导致两个操作以不同的方式执行操作.
假设我有这样的课程:
struct A{
std::string a;
std::string b;
std::string c;
std::string d;
};
Run Code Online (Sandbox Code Playgroud)
如果我使用std::swap,它可能会做这样的事情:
// pseudo-code:
void std::swap(A &a, A &b){
A tmp = std::move(a);
a = std::move(b);
b = std::move(tmp);
}
Run Code Online (Sandbox Code Playgroud)
它将tmp使用默认的c-tor 构建"空"对象- 通常是廉价的操作.然后它有望移动3次,除了疯狂的情况下移动衰变复制.
但是,如果我自己交换:
void swap(A &a, A &b){
std::swap(a.a, b.a);
std::swap(a.b, b.b);
std::swap(a.c, b.c);
std::swap(a.d, b.d);
}
Run Code Online (Sandbox Code Playgroud)
它肯定会使用更少的内存,但它仍然需要构造空std::string- 4次!
我可以疯狂,用单身做std::string.
在所有情况下,它看起来都不是很大的改进.
只有适当的情况我能想到的是,如果默认的c-tor是非常昂贵的.我对么?
我知道我可以使用一些叫做的东西std::vector,但我担心因为课程限制而无法做到这一点.
我需要创建一个动态可扩展的对象数组.当需要存储新对象时,阵列应该增长和增长.
这是该数组所属的类:
class TransactionList
{
private:
Transaction *trans;
int amountTransactions;
Transaction newTrans;
public:
TransactionList();
~TransactionList();
void read( istream &is );
void write( ostream &os );
void add( Transaction & newTrans );
double totalExpenses();
double hasPaid( string namnet );
double isDebted( string namnet );
//PersonList FixPersons();
};
Run Code Online (Sandbox Code Playgroud)
方法"void add(Transaction&newTrans)"是我需要的方法.是的,我认真地必须做指针式.
到目前为止,这种方法完全不完整,甚至还没有接近功能.我已经尝试了几种不同的方法,但最终会出现运行时错误或仅仅是bollocks结果.
void TransactionList::add(Transaction & newTrans)
{
Transaction* tempArrPtr;
amountTransactions++;
trans = new Transaction[amountTransactions]
trans[amountTransactions - 1] = newTrans;
}
Run Code Online (Sandbox Code Playgroud)
我想要的方法是构建一个Transaction-objects数组,并在获取更多对象时增大其大小.
我希望我已经清楚地写了我的问题,希望有人能给我一个很好的答案.我试过谷歌搜索,但我仍然卡住了 - 否则我不会打扰他们:p
如果有人可以给出一些关于复制构造函数的指示,我会非常感激.在我们的课程材料中,他们几乎甚至没有展示复制构造函数应该是什么样子.就像"你需要复制构造进行深度复制,祝你好运!"
给定X下面的类(除了明确定义的特殊成员函数与此实验无关):
struct X
{
X() { }
X(int) { }
X(X const&) { std::cout << "X(X const&)" << std::endl; }
X(X&&) { std::cout << "X(X&&)" << std::endl; }
};
Run Code Online (Sandbox Code Playgroud)
以下程序创建一个类型对象的向量X并调整其大小,以便超出其容量并强制重新分配:
#include <iostream>
#include <vector>
int main()
{
std::vector<X> v(5);
v.resize(v.capacity() + 1);
}
Run Code Online (Sandbox Code Playgroud)
由于class X提供了一个移动构造函数,我希望在重新分配之后将向量的先前内容移动到新存储中.相当令人惊讶的是,情况似乎并非如此,我得到的输出是:
X(X const&)
X(X const&)
X(X const&)
X(X const&)
X(X const&)
Run Code Online (Sandbox Code Playgroud)
为什么?
在C++ 11之前,一直都是复制赋值运算符应该总是通过const引用传递的情况,如下所示:
template <typename T>
ArrayStack<T>& operator= (const ArrayStack& other);
Run Code Online (Sandbox Code Playgroud)
但是,随着移动赋值运算符和构造函数的引入,似乎有些人主张使用pass by value进行复制赋值.还需要添加移动赋值运算符:
template <typename T>
ArrayStack<T>& operator= (ArrayStack other);
ArrayStack<T>& operator= (ArrayStack&& other);
Run Code Online (Sandbox Code Playgroud)
上面的2个运算符实现如下所示:
template <typename T>
ArrayStack<T>& ArrayStack<T>::operator =(ArrayStack other)
{
ArrayStack tmp(other);
swap(*this, tmp);
return *this;
}
template <typename T>
ArrayStack<T>& ArrayStack<T>::operator =(ArrayStack&& other)
{
swap(*this, other);
return *this;
}
Run Code Online (Sandbox Code Playgroud)
在为C++ 11开始创建复制赋值运算符时,使用pass by值是一个好主意吗?我应该在什么情况下这样做?
在以下程序中,我打算通过将char* line内容从一个对象复制到另一个对象strcpy。但是,当程序结束时,析构函数obj2可以正常工作,但会obj导致崩溃。gdb显示line两个对象的不同地址。
class MyClass {
public:
char *line;
MyClass() {
line = 0;
}
MyClass(const char *s) {
line = new char[strlen(s)+1];
strcpy(line, s);
}
~MyClass() {
delete[] line;
line = 0;
}
MyClass &operator=(const MyClass &other) {
delete[] line;
line = new char[other.len()+1];
strcpy(line, other.line);
return *this;
}
int len(void) const {return strlen(line);}
};
int main() {
MyClass obj("obj");
MyClass obj2 = obj;
Run Code Online (Sandbox Code Playgroud) 我只能访问C++ 03,而且我经常想要将一个向量移动到一个函数中,就像在C++ 11中一样.如何做的问题不要过多地混淆代码的用户.所以我的问题是程序员在C++ 11之前是如何做到的.
我知道可以使用交换功能"移动"向量.所以这就是我提出的:
class Foo
{
public:
Foo(std::vector<int>& vec)
{
using std::swap;
swap(vec, m_vec); // "move" vec into member vector
}
private:
std::vector<int> m_vec;
};
// usage:
std::vector<int> v(100, 1337);
Foo foo(v);
// v.empty() == true
Run Code Online (Sandbox Code Playgroud)
这种方法的问题在于,用户不明白他们的矢量将被移动到类Foo中.有这种问题的最佳实践解决方案吗?提前致谢!