我已经完成了第一个数学库版本,下一步我想转向表达式模板来提高代码的性能.但是,我的初步结果与我的预期不同.我正在MSVC 2010中编译,在vanilla Release模式下(并且可以使用C++ 0x).
对于我将向您展示的大量代码提前道歉,在让人们看到我正在做的事情的同时,我尽可能地做到这一点.分析框架:
#include <algorithm>
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iterator>
#include <limits>
#include <type_traits>
#include <vector>
namespace math
{
class vector; // to be determined
std::ostream& operator<<(std::ostream& stream, const vector& vec)
{
for (std::size_t i = 0; i < 4; ++i)
stream << vec[i] << " ";
return stream;
}
}
// test framework
typedef std::vector<math::vector> array_type[3];
typedef std::vector<math::vector> vector_type;
float generate_float()
{
return static_cast<float>(rand());
}
math::vector generate_vector()
{
return math::vector(generate_float(), generate_float(),
generate_float(), generate_float());
} …Run Code Online (Sandbox Code Playgroud) 我想在我的软件中使用类的前向声明,所以我可以使用typedef
并在类完全声明中使用它们.
像这样的Smth:
class myclass;
typedef boost::shared_ptr<myclass> pmyclass;
typedef std::list<pmyclass > myclasslist;
class myclass : public baseclass
{
private: // private member declarations
__fastcall myclass();
public: // public member declarations
__fastcall myclass(myclass *Parent)
: mEntry(new myclass2())
{
this->mParent = Parent;
}
const myclass *mParent;
myclasslist mChildren;
boost::scoped_ptr<myclass2> mEntry;
};
Run Code Online (Sandbox Code Playgroud)
所以我的问题是:这种方法有什么缺点吗?我记得有关前向声明的析构函数问题的一些讨论,但我并没有把所有东西都拿出来.
还是有其他选择来实现这样的东西?
谢谢.
编辑:我找到了我所指的讨论:这里
当一个类有一个简单的构造函数和/或一个普通的析构函数时,C++标准定义了一些非常具体的行为.
例如,根据标准的§3.8/ 1:
类型对象的生命周期在以下情况
T结束:- 如果
T是具有非平凡析构函数(12.4)的类类型,则析构函数调用将启动,或者- 重用或释放对象占用的存储空间.
所以,
虽然这个例子可能不是最好的例子,但它表明行为的差异可能是至关重要的(UB /非UB),无论一个对象是否具有琐事可破坏性.
标准的第12.4/3条规定,T如果一个类的析构函数是隐含的,而不是虚拟的,并且如果所有基类和类的成员T都是可以轻易破坏的,那么(对于sumezeze)类的析构函数是微不足道的.
在我的(适度)体验中,我从未在编译器生成的代码方面看到任何区别:
所以,我的问题是:
我的问题与标准无关(请不要回答标准陈述什么是微不足道的ctor/dtor,所以用户定义的ctor/dtor不是)但是编译器处理用户定义的ctor/dtor的方式以及以何种方式与普通的ctor/dtor相比,编译代码的行为可能会改变(或不改变).
假设我有一些每类数据:(AandB.h)
class A
{
public:
static Persister* getPersister();
}
class B
{
public:
static Persister* getPersister();
}
Run Code Online (Sandbox Code Playgroud)
......还有很多课程.我想做的事情如下:
persistenceSystem::registerPersistableType( A::getPersister() );
persistenceSystem::registerPersistableType( B::getPersister() );
...
persistenceSystem::registerPersistableType( Z::getPersister() );
Run Code Online (Sandbox Code Playgroud)
......为每个班级.
我的问题是:有没有办法自动构建每类数据列表,这样我就不必枚举大块中的每个类型(如上例所示)?
例如,您可以这样做的一种方法是:(AutoRegister.h)
struct AutoRegisterBase
{
virtual ~AutoRegisterBase() {}
virtual void registerPersist() = 0;
static AutoRegisterBase*& getHead()
{
static AutoRegisterBase* head= NULL;
return head;
}
AutoRegisterBase* next;
};
template <typename T>
struct AutoRegister : public AutoRegisterBase
{
AutoRegister() { next = getHead(); getHead() = this; }
virtual void registerPersist()
{
persistenceSystem::registerPersistableType( T::getPersister() …Run Code Online (Sandbox Code Playgroud) 参考这里
该析构函数还将隐式调用auto_ptr对象的析构函数.这将删除它所持有的指针,指向C对象 - 不知道C的定义!它出现在.cpp文件中,其中定义了struct A的构造函数.
这很奇怪然后
5.3.5/5状态 - "如果被删除的对象在删除时具有不完整的类类型,并且完整的类具有非平凡的析构函数或释放函数,则行为是未定义的."
我的问题是,为什么不是这样的程序试图删除指向不完整类型的指针被视为格式错误?为什么它被推入条件领域(而完整的类有一个非平凡的析构函数......)'未定义的行为'?
' 和 '意味着什么?
编辑2:
代码是否格式良好?VS和Gcc/CLang编译,但是Comeau发出警告.我想这一切都是标准中提到的未定义行为的一部分.我的问题是"为什么这不是形成错误但是未定义"?
#include <iostream>
#include <memory>
using namespace std;
struct C;
// Is this the POI for auto_ptr<C>? $14.6.4.1/3
struct A{
A();
auto_ptr<C> mc;
~A(){} // how does it link to C::~C at this point?
};
struct C{};
A::A():mc(new C){}
int main(){
A a;
}
Run Code Online (Sandbox Code Playgroud) 我是 C++ 新手,我正在努力理解的概念之一是析构函数。出于好奇,不必要的(例如,当类没有动态分配的内存、资源或任何需要用户定义的析构函数的东西时)和空的析构函数会导致任何不可预见的问题吗?
编辑:我知道这部分内容已在“空”构造函数或析构函数是否会与生成的构造函数或析构函数执行相同的操作?但我想扩大它的范围,询问更多关于普遍负面后果的问题,例如崩溃或使应用程序变慢。有一些重叠,但这是一个略有不同的问题。