Chinaunix

标题: 虚基类指针 指向新分配的子类 调用构造函数出错 [打印本页]

作者: xuebabybaby    时间: 2013-04-07 22:48
标题: 虚基类指针 指向新分配的子类 调用构造函数出错
本帖最后由 xuebabybaby 于 2013-04-07 23:27 编辑

小弟最近在写中介者模式的代码时, 用给Mediator 虚基类指针 用new分配一个子类ConcreteMediator对象.  Mediator *pM=new ConcreteMediator();
提示错误Main.cpp: (.text+0x9a): undefined reference to 'ConcreteMediator::ConcreteMediator().
可是我已经给ConcreteMediator::ConcreteMediator()写了一个空函数了阿???
为什么不能实例化呢?? 谢谢, 以下是我的代码(关键地方已用红色字)
先给出图:

作者: xuebabybaby    时间: 2013-04-07 22:50
本帖最后由 xuebabybaby 于 2013-04-07 23:15 编辑

// Mediator.h文件:
#ifndef _MEDIATOR_H_
#define _MEDIATOR_H_
class Colleague;  //前向声明
class Mediator
{
        public:
                Mediator();
                ~Mediator();
                virtual void CallA()=0;
                virtual void CallB()=0;
                virtual void SetColleagueA(Colleague *pA)=0;
                virtual void SetColleagueB(Colleague *pB)=0;
        protected:
               
        private:
               
};

class ConcreteMediator:public Mediator
{
        public:

                ConcreteMediator();
                ~ConcreteMediator();
                virtual void CallA();
                virtual void CallB();
                virtual void SetColleagueA(Colleague *pA);
                virtual void SetColleagueB(Colleague *pB);
        protected:
                Colleague *_pA;
                Colleague *_pB;
        private:

};
#endif


作者: xuebabybaby    时间: 2013-04-07 22:51
本帖最后由 xuebabybaby 于 2013-04-08 09:15 编辑
  1. // Mediator.cpp
  2. #include<iostream>
  3. #include "Mediator.h"
  4. #include "Colleague.h"
  5. using namespace std;
  6. Mediator::Mediator()
  7. {

  8. }
  9. Mediator::~Mediator()
  10. {
  11. }
  12. void Mediator::CallA()
  13. {
  14. }
  15. void Mediator::CallB()
  16. {

  17. }
  18. void Mediator::SetColleagueA(Colleague *pA)
  19. {

  20. }
  21. void Mediator::SetColleagueB(Colleague *pB)
  22. {

  23. }
复制代码
//class ConcreteMediator
ConcreteMediator::ConcreteMediator()   //子类构造函数, 就是在子孙类用调用的那个构造函数出错.  Mediator *pM=new ConcreteMediator();出错
{

}

  1. ConcreteMediator::~ConcreteMediator()
  2. {
  3. }
  4. void ConcreteMediator::SetColleagueA(Colleague *pA)
  5. {
  6.          _pA=pA;
  7. }
  8. void ConcreteMediator::SetColleagueB(Colleague *pB)
  9. {
  10.          _pB=pB;
  11. }
  12. void ConcreteMediator::CallA()
  13. {
  14.                  _pA->Operation();
  15. }

  16. void ConcreteMediator::CallB()
  17. {
  18.          if(_pB!=NULL)
  19.          {
  20.                  _pB->Operation();
  21.          }
  22. }
复制代码

作者: xuebabybaby    时间: 2013-04-07 22:52
本帖最后由 xuebabybaby 于 2013-04-08 09:14 编辑
  1. // Colleague.h头文件
  2. #ifndef _COLLEAGUE_H_
  3. #define _COLLEAGUE_H_
  4. class Mediator;  //前向声明

  5. class Colleague
  6. {
  7.          public:
  8.                  Colleague();
  9.                  ~Colleague();
  10.                  virtual void SetMediator(Mediator *pM)=0;
  11.                  virtual void Operation()=0;
  12.          protected:

  13.          private:
  14. };

  15. class ConcreteColleagueA:public Colleague
  16. {
  17.          public:
  18.                  ConcreteColleagueA();
  19.                  ~ConcreteColleagueA();
  20.                  virtual void SetMediator(Mediator *pM);
  21.                  virtual void Operation();
  22.                  void CallB();
  23.          protected:
  24.                  Mediator *_pMediator;
  25.          private:

  26. };

  27. class ConcreteColleagueB:public Colleague
  28. {
  29.          public:
  30.                  ConcreteColleagueB();
  31.                  ~ConcreteColleagueB();
  32.                  virtual void SetMediator(Mediator *pM);
  33.                  virtual void Operation();
  34.                  void CallA();
  35.          protected:
  36.                  Mediator *_pMediator;
  37.          private:
  38. };

  39. #endif
复制代码

作者: xuebabybaby    时间: 2013-04-07 22:53
本帖最后由 xuebabybaby 于 2013-04-08 09:10 编辑

这个代码基本可以不看,少占用您一点时间:
  1. // Colleague.cpp 文件:
  2. #include<iostream>
  3. #include "Mediator.h"
  4. #include "Colleague.h"
  5. using namespace std;
  6. //class Colleague
  7. Colleague::Colleague()
  8. {

  9. }
  10. Colleague::~Colleague()
  11. {

  12. }

  13. //class ConcreteColleagueA
  14. ConcreteColleagueA::ConcreteColleagueA()
  15. {
  16.         _pMediator=NULL;
  17. }

  18. ConcreteColleagueA::~ConcreteColleagueA()
  19. {
  20.        
  21. }

  22. void ConcreteColleagueA::SetMediator(Mediator *pM)
  23. {
  24.         _pMediator=pM;
  25. }

  26. void ConcreteColleagueA::Operation()
  27. {
  28.         cout<<"Operation of A is called"<<endl;

  29. }
  30. void ConcreteColleagueA::CallB() //A调用B的Operation
  31. {
  32.         _pMediator->CallB();
  33. }

  34. //class ConcreteColleagueB
  35. ConcreteColleagueB::ConcreteColleagueB()
  36. {
  37.         _pMediator=NULL;
  38. }

  39. ConcreteColleagueB::~ConcreteColleagueB()
  40. {
  41. }

  42. void ConcreteColleagueB::SetMediator(Mediator *pM)
  43. {
  44.         _pMediator=pM;
  45. }

  46. void ConcreteColleagueB::Operation()
  47. {
  48.         cout<<"Operation of B is called"<<endl;
  49. }

  50. void ConcreteColleagueB::CallA()//B调用A的Operation
  51. {
  52.         _pMediator->CallA();
  53. }
复制代码

作者: xuebabybaby    时间: 2013-04-07 22:57
// Main.cpp文件
#include<iostream>
#include"Mediator.h"
#include"Colleague.h"
using namespace std;

int main()
{
        //Mediator *pM=new ConcreteMediator();//中价者, //这样写也出错
              Mediator *pM=new ConcreteMediator;       // 错误定但到这一行,

        ConcreteColleagueA *pA=new ConcreteColleagueA();//A
        ConcreteColleagueB *pB=new ConcreteColleagueB();//B
       
        //A和B认识中介者       
              pA->SetMediator(pM);
        pB->SetMediator(pM);

        //中介者认识A和B
        pM->SetColleagueA(pA);
        pM->SetColleagueB(pB);

        pA->CallB();//A调用B的Operation
        pB->CallA();//B调用A的Operation
}

作者: xuebabybaby    时间: 2013-04-07 23:07
这个附件是类的继承关系, 多谢了.. 我在网上找了很久.  自己也想了两天都想不出来.   我自己试过用虚基类的指针指向其子类对象是可以的.  这里为什么不行呢
谢谢.

20130407.png (9.57 KB, 下载次数: 56)

20130407.png

作者: xuebabybaby    时间: 2013-04-07 23:08
用 Mediator *pM=new ConcreteMediator; 出错
作者: linux_c_py_php    时间: 2013-04-07 23:16
尼玛,让C++毒害了的楼主,快到我碗里来。
作者: xuebabybaby    时间: 2013-04-07 23:18
回复 9# linux_c_py_php


    晕....  碗里有妞吗??
帮我看一下代码,谢谢
作者: xuebabybaby    时间: 2013-04-07 23:22
本帖最后由 xuebabybaby 于 2013-04-07 23:37 编辑

我的makefile:
  1. a.out: Mediator.o Colleague.o Main.o  #注释targert
  2.         g++ -o Mediator.o Colleague.o Main.o       
  3. Mediator.o: Mediator.cpp Mediator.h Colleague.h
  4.         g++ -c Mediator.cpp
  5. Colleague.o:Colleague.cpp Mediator.h Colleague.h
  6.         g++ -c Colleague.cpp
  7. Main.o: Main.cpp Mediator.h Colleague.h
  8.         g++ -c Main.cpp
  9. clean:
  10.         rm -f Mediator.o Colleague.o Main.o a.out
复制代码

作者: kongrenxin    时间: 2013-04-08 08:46
没细看,但挑出两个地方说一下:
1. Mediator基类的析构函数应该变为虚函数,否则在delete基类指针时,将不会delete所指向的派生类。
2. Mediator基类的那些纯虚函数,为什么还要它自己去实现? 纯虚函数只是为了提供一个统一的接口,实现留给派生类去做。
作者: xuebabybaby    时间: 2013-04-08 09:17
回复 12# kongrenxin


    谢谢.

还有, 我现在已经把提示错误的地方用红色字了.  在3楼的构造函数, 和6楼调用这个构造函数出错.   你能帮我看一下么?谢谢.......
作者: kongrenxin    时间: 2013-04-08 09:28
再看了一下,编译不通过其实是你的Makefile有问题:
        g++ -o Mediator.o Colleague.o Main.o  
要么就不指-o选项,默认生成a.out,既然指定了-o选项,那也要对应给生成的二进制文件指定一个名字啊。。。。
作者: xuebabybaby    时间: 2013-04-08 21:38
本帖最后由 xuebabybaby 于 2013-04-08 21:39 编辑

回复 14# kongrenxin


    谢谢你,  就是makefile我写错了,程序没错.  按照你的方法加上指定输出的文件名a.out. 然后就可以了.:wink:
作者: thaldn    时间: 2013-04-09 20:17
费了点时间看了看,还好看到了14楼,没有浪费时间




欢迎光临 Chinaunix (http://bbs.chinaunix.net/) Powered by Discuz! X3.2