背景
我试图自己实现std :: vector。现在,我只有它的专用版本,它有MyStruct实例作为元素。元素类型具有辅助输出,如信号的构造方式(复制,移动,值,默认ctor)。我添加了运算符的重载<<使调试更方便。我正在使用Microsoft Visual Studio 2015更新1.
问题:
首先,似乎emplace_back调用没有做它应该做的事情。试图输出返回元素它输出垃圾。另外,当退出main()的范围时,有错误说程序试图写入堆外的内存。添加了消息框的图像。
修改
推回几乎相同的增加容量的实现工作。还添加了实现和声明。
以下是代码:
的main.cpp
#include "MyStruct.h"
#include <iostream>
#include <cstdlib>
#include "vector.h"
int main()
{
MyStruct ms(0);
Vector v;
v.emplace_back(2);
std::cout << v.back() << "\n";
std::system("pause");
}
vector.h
#pragma once
#include "MyStruct.h"
class Vector
{
size_t mcapacity;
MyStruct* mdata;
size_t msize;
public:
Vector();
MyStruct& back();
void push_back(const MyStruct& ms);
template<typename ... ArgsType>
void emplace_back(ArgsType ... args)
{
if (mcapacity == msize && msize == 0)
{
mdata = (MyStruct*)operator new[](sizeof(MyStruct));
mcapacity++;
}
else if (mcapacity == msize)
{
MyStruct* tempdata = (MyStruct*)operator new[](sizeof(MyStruct) * mcapacity * 2);
for (size_t i = 0; i < msize; i++)
{
new (tempdata + i) MyStruct(*(mdata + i));
}
mdata = tempdata;
mcapacity *= 2;
}
new (mdata + msize) MyStruct(std::forward<ArgsType...>(args...));
msize++;
}
~Vector();
};
vector.cpp
#include "vector.h"
#include "MyStruct.h"
#include <iostream>
Vector::Vector() :
mdata(nullptr),
msize(0),
mcapacity(0)
{
}
MyStruct& Vector::back()
{
return *(mdata + msize - 1);
}
void Vector::push_back(const MyStruct& ms)
{
if (mcapacity == msize && msize == 0)
{
mdata = (MyStruct*)operator new[](sizeof(MyStruct));
mcapacity++;
}
else if (mcapacity == msize)
{
MyStruct* tempdata = (MyStruct*)operator new[](sizeof(MyStruct) * mcapacity * 2);
for (size_t i = 0; i < msize; i++)
{
new (tempdata + i) MyStruct(*(mdata + i));
}
mdata = tempdata;
mcapacity *= 2;
}
new (mdata + msize) MyStruct(ms);
msize++;
}
Vector::~Vector()
{
for (size_t i = 0; i < msize; i++)
{
(mdata + i)->~MyStruct();
}
operator delete[](mdata);//next statement to execute
}
输出:
I'm constructed using value constructor
I'm constructed using value constructor
I'm printing the number -33686019!
这是MyStruct标头和实现,但我认为没有任何函数抛出任何异常或调用未定义的行为。添加了所有构造函数,因为我不确定在调用v.back()时实际调用了哪个构造函数。认为编译器可能会进行一些优化。但根据输出,价值ctor被称为。
MyStruct.h
#pragma once
#include <iosfwd>
class MyStruct
{
int x;
public:
MyStruct();
MyStruct(int x_);
MyStruct(const MyStruct& other);
MyStruct(MyStruct&& other) noexcept;
void print(std::ostream& os) const;
~MyStruct();
};
std::ostream& operator<<(std::ostream& os, const MyStruct& ms);
MyStruct.cpp
#include "MyStruct.h"
#include <iostream>
MyStruct::MyStruct():
x(0)
{
std::cout << "I'm created using default constructor" << "\n";
}
MyStruct::MyStruct(MyStruct&& other) noexcept :
x(other.x)
{
std::cout << "I'm created using move constructor" << "\n";
}
MyStruct::MyStruct(const MyStruct& other):
x(other.x)
{
std::cout << "I'm created using copy constructor" << "\n";
}
MyStruct::~MyStruct()
{
std::cout << "I'm destructed" << "\n";
}
void MyStruct::print(std::ostream& os) const
{
os << "I'm printing the number " << x << "!\n";
}
std::ostream& operator<<(std::ostream& os, const MyStruct& ms)
{
ms.print(os);
return os;
}
MyStruct::MyStruct(int x_) :
x(x_)
{
std::cout << "I'm constructed using value constructor" << "\n";
}