具有多个类的C ++新对象

时间:2012-03-06 23:57:52

标签: c++ class object namespaces

所以我有一个主文件和两个类:一个显示类和一个作业类。

我想要实现的是,主类能够调用显示类,以及与作业类的接口,但我也希望Job类能够从Display类调用方法,也将参数发送到显示类。

我已经尝试了多种方法来解决当前的问题,但我无法完成我想要的,我听说过命名空间,但我不熟悉它们,我不确定这是否是我需要的。

我还尝试从main传递Job / Display对象,但是由于在我的标题中我已经最终定义了一个新对象,因此无法解决我想要做的事情。

以下是我想要实现的一些示例代码(请忽略简单的编译器错误/这只是示例代码,我不会发布我的整个项目,因为这将是long / Ignore标头):< / p>

Main.cpp的

 int main(){
    Display display;
    Job job;
    job.init();
    display.test();
    return 0;
}

Display.cpp

 void Display::test(){
     std::cout << "testing.." << std::endl;
 }

 void Display::test2(std::string ttt){
     Job job; //Do not want to create a whole new object here
     std::cout << "testing3333...." << job.getThree() << std::endl;
     std::cout << "testing2222...." <<  ttt << std::endl;
 }

Job.cpp

 void Job::init(){
      Display disp2; //I do not want to create a whole new object here, but I can't fix this
      disp2.test2("from Job");
 }

 std::string Job::getThree(){
       return "test3";
 }

Job.h

class Job{
private:
    Display disp; // Do not want a new object here as well
public:
    void init();
    std::string getThree();
};

3 个答案:

答案 0 :(得分:3)

您需要将Job指针传递给Display,反之亦然,这样他们才能相互了解,例如:

主:

#include "Display.h"
#include "Job.h"

int main()
{ 
    Display display; 
    Job job; 
    display.init(&job);
    job.init(&display); 
    display.test(); 
    return 0; 
} 

Display.h:

class Job;

class Display
{
private:
    Job *_job;
public:
    Display();
    void init(Job *job);
    void test();
    void test2(const std::string &ttt);
};

Display.cpp:

#include "Display.h"

Display::Display()
    : _job(NULL)
{
}

void Display::init(Job *job)
{
    _job = job;
}

void Display::test()
{ 
    std::cout << "testing.." << std::endl; 
} 

void Display::test2(const std::string &ttt)
{ 
    std::cout << "testing3333...." << _job->getThree() << std::endl; 
    std::cout << "testing2222...." << ttt << std::endl; 
} 

Job.h:

class Display;

class Job
{
private:
    Display *_display;
public:
    Job();
    void init(Display *display);
    std::string getThree();
};

Job.cpp:

#include "Job.h"

Job::Job()
    : _display(NULL)
{
}

void Job::init(Display *display)
{ 
    _display = display;
    _display->test2("from Job"); 
} 

std::string Job::getThree()
{ 
    return "test3"; 
} 

根据您提到的要求,Display并不需要记住Job,只有Job需要记住Display,所以您可以做某事像这样替代:

主:

#include "Display.h"
#include "Job.h"

int main()
{ 
    Display display; 
    Job job;
    job.init(&display); 
    display.test(); 
    return 0; 
} 

Display.h:

class Job;

class Display
{
public:
    void test();
    void test2(Job *job);
};

Display.cpp:

#include "Display.h"

void Display::test()
{ 
    std::cout << "testing.." << std::endl; 
} 

void Display::test2(Job *job)
{ 
    std::cout << "testing3333...." << job->getThree() << std::endl; 
} 

Job.h:

class Display;

class Job
{
private:
    Display *_display;
public:
    Job();
    void init(Display *display);
    std::string getThree();
};

Job.cpp:

#include "Job.h"

Job::Job()
    : _display(NULL)
{
}

void Job::init(Display *display)
{ 
    _display = display;
    _display->test2(this); 
} 

std::string Job::getThree()
{ 
    return "test3"; 
} 

答案 1 :(得分:0)

您似乎手头有一个基本的OOP问题。这里有一些问题可能会引导您朝着正确的方向前进。

您的课程需要多少个课程实例?

这取决于你要解决的问题,所以只有你能给出正确答案。

  1. 如果您只需要两个类的一个实例,那么只需检索单例实例,使它们singleton并且两者都可以相互访问。

  2. 如果您需要一个显示实例和多个作业实例,则需要将Job实例存储在一个Display实例可以访问的容器中。您需要将Display设为singleton,以便随意访问。

  3. 如果你需要两个实例,那么你需要通过将已经创建的对象传递给另一个的构造函数来显式关联那些需要协同工作的实例。

  4. 想一想:

    Display d1, d2;
    Job j1(&d1), j2(&d2); // make sure not to copy the displays!
    

    并在Job构造函数中:

    Job(Display *display): display(display) {
        display->setJob(this);
    }
    

    如果每个作业需要多个显示,则必须用Job display指针集合替换Job中的单个Display指针,并手动将相应的显示添加到该集合中。


    如果这没有帮助,您需要向我们解释您正在解决的问题,我们可能会进一步提供帮助。

答案 2 :(得分:0)

您需要了解C ++中的引用和指针。

这些是对现有对象的访问(想想“链接到”)。两者之间的主要区别在于,如果您提供对象的引用,则可以保证在传递时该对象存在。如果你给出一个指针,它后面可能没有任何东西,这在最近的版本中被称为“空”指针(写成NULLnullptr)。

以下是使用两者的主要方式:

int i = 0;

int& refToI = i; // create a reference to i
int* ptrToI = &i; // create a pointer to i

int& anotherRef; // invalid, references must be initialized;
int* anotherPtr; // valid, points to garbage data, better set it to NULL though

refToI = 1; // i has been changed
*ptrToI = 1; // i has been changed, the "*" operator means "content pointed by"

接受引用或指针的对象(或函数)必须阐明它们对指向对象的期望。也就是说,一旦创建了引用或指针,它所指向的对象也可能被破坏。这很糟糕,避免它。

以下是您的案例中的一些示例:

// Solution 1 take a reference to the objet in the function using it

class Job; // tells the compiler that there's a Job class somewhere.

class Display
{
public:
    void DoWork(Job& job) {
        // write this in the CPP file, I am using a shortcut for the sake of brevity
        job.DoSomething();
    }
};

// usage:
Display display;
Job job;
display.DoWork(job);



// Solution 2, carry the reference (or pointer) inside the class using it

class Job; // tells the compiler that there's a Job class somewhere.

class Display
{
public:
    Display(Job& job) // !! job must live at least as long as display
        : _job(job)
    { }

    void DoWork() {
        // write this in the CPP file, I am using a shortcut for the sake of brevity
        _job.DoSomething();
    }

private:
    Job& _job;
};


// Usage:
Job job;
Display display(job); // job and display have the same lifetime, OK
display.DoSomething();

关于是否应该使用指针或引用存在争议。我觉得现在对你来说有点困难。经验法则是在生命周期众所周知时使用引用,当它们不使用时或使用new时使用 smart 指针。