如何在另一个类中使用构造函数创建对象?

7

我正在处理一个采用模块化设计的代码。其中,我的一个类名为Splash,需要创建另一个称为Emitter的类的对象。通常情况下,您只需创建对象并完成操作即可,但是这里不起作用,因为Emitter类具有自定义构造函数。但是当我尝试创建对象时,它却无法工作。

以一个例子来说明;

Emitter具有以下构造函数:Emitter::Emitter(int x, int y, int amount);,需要被创建以便在Splash类中进行访问。

我尝试了以下方法,但它没有起作用:

class Splash{
    private:
        Emitter ps(100, 200, 400, "firstimage.png", "secondimage.png"); // Try to create object, doesn't work.
    public:
       // Other splash class functions.
}

我也尝试了这个方法,但它也不起作用:
class Splash{
    private:
        Emitter ps; // Try to create object, doesn't work.
    public:
       Splash() : ps(100, 200, 400, "firstimage.png", "secondimage.png")
       {};
}

编辑:我知道第二种方法应该可以工作,但实际上并没有。如果我删除Emitter部分,代码就能正常运行。但是当我采用第二种方式时,没有窗口打开,也没有执行任何应用程序。

那么我该如何创建我的Emitter对象以供在Splash中使用?

编辑:

这是我的发射器类和头文件的代码:Header

// Particle engine for the project

#ifndef _PARTICLE_H_
#define _PARTICLE_H_

#include <vector>
#include <string>
#include "SDL/SDL.h"
#include "SDL/SDL_image.h"
#include "image.h"

extern SDL_Surface* gameScreen;

class Particle{
    private: // Particle settings
        int x, y;
        int lifetime;
    private: // Particle surface that shall be applied
        SDL_Surface* particleScreen;
    public: // Constructor and destructor
        Particle(int xA, int yA, string particleSprite);
        ~Particle(){};
    public: // Various functions
        void show();
        bool isDead();
};

class Emitter{
    private: // Emitter settings
        int x, y;
        int xVel, yVel;
    private: // The particles for a dot
        vector<Particle> particles;
        SDL_Surface* emitterScreen;
        string particleImg;
    public: // Constructor and destructor
        Emitter(int amount, int x, int y, string particleImage, string emitterImage);
        ~Emitter();
    public: // Helper functions
        void move();
        void show();
        void showParticles();
};

#endif

这里是发射器函数:

#include "particle.h"

// The particle class stuff
Particle::Particle(int xA, int yA, string particleSprite){
    // Draw the particle in a random location about the emitter within 25 pixels    
    x = xA - 5 + (rand() % 25);
    y = yA - 5 + (rand() % 25);
    lifetime = rand() % 6;
    particleScreen = Image::loadImage(particleSprite);
}

void Particle::show(){
    // Apply surface and age particle
    Image::applySurface(x, y, particleScreen, gameScreen);
    ++lifetime;
}

bool Particle::isDead(){
    if(lifetime > 11)
        return true;
    return false;
}

// The emitter class stuff

Emitter::Emitter(int amount, int x, int y, string particleImage, string emitterImage){
    // Seed the time for random emitter
    srand(SDL_GetTicks());
    // Set up the variables and create the particles
    x = y = xVel = yVel = 0;
    particles.resize(amount, Particle(x, y, particleImage));
    emitterScreen = Image::loadImage(emitterImage);
    particleImg = particleImage;
}

Emitter::~Emitter(){
    particles.clear();
}

void Emitter::move(){
}

void Emitter::show(){
    // Show the dot image.
    Image::applySurface(x, y, emitterScreen, gameScreen);
}

void Emitter::showParticles(){
    // Go through all the particles
    for(vector<Particle>::size_type i = 0; i != particles.size(); i++){
        if(particles[i].isDead() == true){
            particles.erase(particles.begin() + i);
            particles.insert(particles.begin() + i, Particle(x, y, particleImg));
        }
    }
    // And show all the particles
    for(vector<Particle>::size_type i = 0; i != particles.size(); i++){
        particles[i].show();
    }
}

这里还有Splash类Splash头文件


1
第二个版本是正确的方法,它“应该”可以工作。你有收到错误吗?如果有,是什么类型的错误? - jrok
类Splash声明末尾缺少分号? - djfm
没有任何输出。它可以编译,但是没有任何反应。@Cheersandhth.-Alf 我会尝试给出一个例子。 - Rivasa
抱歉,忘记了那个问题,已经修复了。 - Rivasa
好的,问题已解决,我刚刚想了个变通方法。 - Rivasa
显示剩余6条评论
2个回答

11
第二个选项应该有效,我建议查找编译错误以确定原因。请发布与此代码相关的任何编译错误。 同时,您可以执行以下操作:
class Splash{
   private:
     Emitter* ps;
   public:
     Splash() { ps = new Emitter(100,200,400); }
     Splash(const Splash& copy_from_me) { //you are now responsible for this }
     Splash & operator= (const Splash & other) { //you are now responsible for this}

     ~Splash() { delete ps; }

};

2
你能详细说明一下为什么这会有帮助吗? - juanchopanza
@juanchopanza 代码应该可以编译、工作,并且满足他的需求。然而,我猜测它仍然无法正常工作,因为他的问题不在他发布的代码中,而是与发射器类中的其他地方有关。无论如何,这将揭示问题所在。 - Jonathan Henson
3
听从使用指针的建议可能会引入额外的问题,而不是修复问题。特别是,给定的代码违反了三大法则之一。也就是说,如果 Splash 的任何实例被复制,它将会产生意想不到的问题。 - Cheers and hth. - Alf
@Pototo 我并不是在建议使用动态内存,只是这样做可以帮助 OP 更容易地找到问题。 - Jonathan Henson
好的,我明白了。 - Pototo
显示剩余3条评论

0

好的,我设法修复了它,虽然是以hackish的方式。 我所做的是创建一个默认构造函数,并将我的普通构造函数代码移入一个新函数中。 然后我创建了对象并调用了新的初始化函数来设置所有内容。


2
这表明您的代码存在错误。我看到您有一个析构函数,但没有复制构造函数或赋值运算符,您是否遵循“三大法则”(Rule of Three)?不要创建hack,而是创建fixes。 - GManNickG
我的闪屏类不需要复制构造函数,因为程序开始时只创建了一个,然后被销毁。此外,闪屏类的析构函数只是默认的。 - Rivasa
  1. 如果不需要,就删除它(C++11),或者声明但不定义它(C++03)。
  2. 好的,但是除非你打算添加自定义行为,否则永远不要编写析构函数,让编译器来处理。
- GManNickG
你也可以将复制构造函数和赋值运算符设为私有,并给它们一个空的定义。这样,任何使用该类的人在尝试进行复制或赋值时都会收到编译器错误。 - Jonathan Henson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接