More Effective C++之27

原创 2006年06月23日 17:22:00
条款27:要求(或禁止)对象产生于heap之中
要求对象产生于Heap之中 Heap-Based Objects
       考虑如下代码:
classHeapClass
{
public:
       voidDestory() const {deletethis;}
private:
       ~HeapClass(){}
};
HeapClass* ptr = newHeapClass;
ptr->Destory();
这样的调用真是很厉害,想生成非Heap对象都不成了。
对于继承和组合的情况不想多说了,比较无趣的说。
 
判断某个对象是否位于Heap内
考虑如下代码:
newHeapClass(* newHeapClass);
你觉得编译器应该怎么做?
1.
调用operator new
2.
调用Constructor
3.
调用第二个operator new
4.
调用第二个Constructor
但是可以让人足够惊讶,编译器对此并不做承诺,所以实际的实现可能是
1.
调用operator new
2.调用第二个operator new
3.
调用Constructor
4.
调用第二个Constructor
我知道VC6是这样实现的。
classHeapClass
{
private:
      
       void* operatornew[](size_tsize);
       typedefconstvoid * RawAddress;
       voidoperatordelete[](void* ptr);
public:
       voidoperatordelete(void *ptr)
          {
                 printf("delete/n");
                 ::operatordelete(ptr);
                 m_address.erase(
                    std
::remove(m_address.begin(),m_address.end(),ptr),m_address.end());
                 return;
          }
       void* operatornew(size_tsize)
          {
                 printf("new/n");
                 void * ptr = ::operatornew(size);
                 m_address.push_back(ptr);
                 returnptr;
          }
       HeapClass()
       {
              printf("Constructor!/n");
       }
       HeapClass(constHeapClass&)
       {

              printf("copy Constructor!/n");

       }
       virtualvoidDestory() const {deletethis;}
       virtual ~HeapClass() = 0;
       boolisOnHeap() const
       {

//            const void * rawAddress = dynamic_cast<const void *>(this);

              constvoid * rawAddress = (constvoid *)(this);
              std::deque<RawAddress>::iteratoriter = std::find(m_address.begin(),m_address.end(),rawAddress);
              returniter != m_address.end();
       }
private:
       staticstd::deque<RawAddress> m_address;
};
 
HeapClass::~HeapClass(){}
std::deque<HeapClass::RawAddress> HeapClass::m_address;
classDHeapClass:publicHeapClass
{
};

我在VC6中写了这个Demo测试了一下,但是const void * rawAddress = dynamic_cast<const void *>(this);会出现异常,这让我觉得很郁闷,所以这个Demo只能支持普通的继承方式,不支持多种继承和虚拟继承。

 
禁止对象产生于heap之中
       考虑如下代码
classHeapClass
{
private:
       void* operatornew(size_tsize);
       void* operatornew[](size_tsize);
voidoperatordelete(void *ptr);
voidoperatordelete[](void* ptr);
public:
       HeapClass(){printf("Constructor!/n");}

       HeapClass(constHeapClass&){printf("copy Constructor!/n");}

public:
       ~HeapClass(){}
};
这确实是比较简单的事情。

《More Effective C++》条款27:如何让类对象只在栈(堆)上分配空间?

一般情况下,编写一个类,是可以在栈或者堆分配空间。但有些时候,你想编写一个只能在栈或者只能在堆上面分配空间的类。这能不能实现呢?仔细想想,其实也是可以滴。 在C++中,类的对象建立分为两种,一种...

《More Effective C++》条款27:如何让类对象只在栈(堆)上分配空间?

昨天一个同学去网易面试C++研发,问到了这么一个问题:如何限制一个类对象只在栈(堆)上分配空间? 一般情况下,编写一个类,是可以在栈或者堆分配空间。但有些时候,你想编写一个只能在栈或者只能在堆上面分...
  • hxz_qlh
  • hxz_qlh
  • 2013年10月26日 21:27
  • 5972

More Effective C++:Item 27

温习More Effective C++,对于Item 27:要求或禁止在堆中产生对象,整理思路于此文。编译期控制通过禁用编译器产生对象所需的选项即可在编译期阻止对象被定义。产生堆对象所需的选项: ...

《More Effective C++》条款27:如何让类对象只在栈(堆)上分配空间?

昨天一个同学去网易面试C++研发,问到了这么一个问题:如何限制一个类对象只在栈(堆)上分配空间? 一般情况下,编写一个类,是可以在栈或者堆分配空间。但有些时候,你想编写一个只能在栈或者只能在堆上...

《More Effective C++》重点摘要二:操作符

对定制的“类型转换函数”警觉。两种函数允许编译器执行类型转换:1)单变量constructors;2)隐式类型转换操作符。第一种函数可以是明确只有一个单变量的constructor,也可以是拥有除第一...

more effective c++之Item M1:指针与引用的区别

1.参数为引用不用判断为空,指针需要判断空指针; 2.有些函数返回应用比返回指针从语法和形式上更好,例如重载operator [ ]。 指针与引用看上去完全不同(指针用操作符“*”和“->...

More Effective C++读书笔记(五)

技术 条款25:将构造函数和非成员函数虚拟化 1.虚拟构造函数是指能够根据输入给它的数据的不同而建立不同类型的对象,比如从磁盘读取对象信息。 2.被派生类重定义的虚拟函数不用必须与基类的虚拟函数...
  • necrazy
  • necrazy
  • 2013年11月08日 10:11
  • 815

《More Effective C++》7:千万不要重载 &&, ||, 和 ,操作符

《More Effective C++》Rule7:千万不要重载 &&, ||, 和 ,操作符

看了下More Effective C++,做了点小结

今天主要是学习More Effective C++ 1) 指针和引用的使用 指针:在对象为空时;不同的时刻指向不同的对象时 引用:总指向一个对象,并且一旦指向这个对象就不再改变时; 当时重载某个...

前置和后置操作符的区别(More Effective_C++_6(运算符))

++和–的原理类似,下面仅++操作符来分析前置和后置的区别先看一段代码:class A{ pubilc: A& operator++();//前置++ const A& operator++(int)...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:More Effective C++之27
举报原因:
原因补充:

(最多只允许输入30个字)