C ++类方法在其他方法之前运行

时间:2014-02-01 21:23:27

标签: c++

我过去曾经使用过这个网站,从来没有真正发布过一个问题,但我不确定如何简单地说出来。我在Devry的C ++课程中,我项目的实际作业需求方面已经完成,但我正在为练习添加一些元素。

因此,为了完成家庭作业,我又添加了一个名为Song的课程。它有2个私有变量(标题和长度),一些基本构造函数和=和==的操作重载。一切正常。然后我将一个Song类的数组添加到Cd类(每个Cd的最大歌曲数为10)。我为Cd创建了一些新的方法:

  • addSong(Song s);
  • removeSong(Song s);
  • organizeSong();和
  • 修改Report()const;

根据选择的数量按顺序写出歌曲。现在,选择和播放时间的Cd私有值分别与歌曲的总数和这些歌曲的总长度相关联。一切正常。 removeSong将指定的歌曲从列表中取出,然后调用organizeSong将剩余的歌曲设置为数组中的最低值。然而,似乎无论我在哪里调用removeSong(Song s),它都会在任何事物写入程序之前删除它。 因此,以下代码将从Cd中提取信息,但只有一首歌,尽管在Report方法之后调用了removeSong方法。任何人都有任何想法,为什么会这样?

Song s1("Hey Jude", 4.52);
Song s2("The song of Pie", 3.14);

Cd c1 ("Beatles", "Capitol");
c1.addSong(s1);
c1.addSong(s2);
cout<< "Using object directly: \n";
c1.Report();

c1.removeSong(s1);

报告方法如下所示:

void Cd::Report () const
{

    cout<< "Performers: " << performers << endl << "Label: " <<label << endl << "Selections: " << selections <<endl << "Playtime: " << playtime << endl;
    for(int i = 0; i < selections; i++)
    {
        cout << "Song " << i+1 << ": " << song[i].getTitle() << " Length: " << song[i].getLength() << endl;
    }

}

澄清。我用更多的歌曲测试了这个,没有调用removeSong方法,它会写出数组中的所有歌曲。

编辑* * 我正在添加其余的代码以希望澄清我的问题。我还没有兴趣使它保持线程安全或更高效,除了向我的教师演示继承和类的组合之外,它没有任何目的,它已经超出了我们的任务要求。我很欣赏有关如何使代码更好的评论,并将调查这些内容,但我想弄清楚为什么removeSong在主代码中的removeSong之前报告时会影响Report的输出。我已经测试了不同的方法和重载,它们都按照预期的方式工作,它只是我感兴趣的removeSong发生的时间。它删除了正确的歌曲并正确地重新排列了现有的歌曲,它只是为了很快:在调用第一个报告之前。 (我确实需要在报告中更改大写以保持一致性)。我大多肯定这是一个基本的东西,我在这里缺少新的东西。

主要代码:

// GSP125_Davis_lab4_partA.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include <conio.h>
#include "classic.h"
#include <string.h>
///Prototypes
void Bravo(const Cd & disk);

Song s1("Hey Jude", 4.52);
Song s2("the Song of Pie",3.14);
Song s3("National Anthem", 5.55);

char* userInput = "null";
char str[20] = "null";
bool bol_end = false;
int main()
{

    Cd c1 ("Beatles", "Capitol");
    c1.addSong(s1);
    c1.addSong(s2);
    c1.addSong(s3);
    Cd *pcd = &c1;
    Classic c2("Piano Sonata in B flat, Fantasia in C", "Alfred Brendel", "Phillips");
    c2.addSong(s2);
    c2.addSong(s3);
    c2.addSong(s1);

    cout << "Using object directly:\n";
    //this is where the code seems to have an issue. as you see Report is called
    //then after c1.removeSong(s1) is called.  s1 is removed properly but this first
    // c1.Report() reflects the changes removeSong makes.
    c1.Report();
    c2.Report();
    c1.removeSong(s1);

    cout << "Using type Cd method for cd object:\n";

    pcd->Report();
    pcd = &c2;
    pcd-> Report();

    cout<< "Calling a function with a Cd reference argument:\n";
    Bravo(c1);
    Bravo(c2);

    cout << "Testing assignment: \n";
    Classic copy;
    copy = c2;
    copy.Report();

    cout << "Press any key to continue...";
    _getch();
    return 0;

}

void Bravo(const Cd & disk)
{
    disk.Report();
}

Cd.cpp

#include "StdAfx.h"
#include "cd.h"



Cd::Cd(char * s1, char * s2) 
{
    strcpy(performers, s1);
    strcpy(label, s2);
    selections = 0;
    playtime = 0;
    for(int i = 0; i < songLimit; i++)
    {
        song[i] =  Song();
    }
}
Cd::Cd(const Cd & d)
{
    strcpy(performers, d.performers);
    strcpy(label, d.label);
    selections = d.selections;
    playtime = d.playtime;
    for(int i = 0; i < songLimit; i++)
    {
        song[i] = d.song[i];
    }
}
Cd::Cd()
{
    strcpy(performers, "None");
    strcpy(label, "No one");
    selections = playtime = 0;
    for(int i = 0; i < songLimit; i++)
    {
        song[i] = Song();
    }
}

Cd::~Cd(void)
{
}
void Cd::Report () const
{

    cout<< "Performers: " << performers << endl << "Label: " <<label << endl << "Selections: " << selections <<endl << "Playtime: " << playtime << endl;
    for(int i = 0; i < selections; i++)
    {
        cout << "Song " << i+1 << ": " << song[i].getTitle() << " Length: " << song[i].getLength() << endl;
    }

}
void Cd::addSong(Song s)
{
    for (int i = 0; i < songLimit; i++)
    {

        if (song[i].getTitle() == "none")
        {
            song[i] = s;
            selections++;
            playtime+= s.getLength();
            break;
        }
    }
}
void Cd::removeSong(Song s)
{
    for (int i = 0; i < songLimit; i++)
    {
        if(song[i] == s)
        {
            song[i] = Song();
            selections--;
            playtime-= s.getLength();
            break;
        }
    }
    organizeSong();
}
void Cd::organizeSong() 
{

    int empty = -1;
        for (int i = 0; i < songLimit; i++)
        {
            if(song[i].getTitle() == "none" && empty == -1)
            {
                empty = i;
            }
            else if (empty != -1)
            {
                song[empty] = song[i];
                song[i] = Song();
                empty = i;
            }
        }

}
Cd & Cd::operator=(const Cd & d)
{
    strcpy(performers, d.performers);
    strcpy(label, d.label);
    selections = d.selections;
    playtime = d.playtime;
    for(int i = 0; i < songLimit; i++)
    {
        song[i] = d.song[i];
    }
    return *this;
}

Song.cpp

#include "StdAfx.h"
#include "Song.h"



Song::Song(char* s, double l)
{
    title = s;
    length = l;
}

Song::Song(const Song & s)
{
    title = s.title;
    length = s.length;
}
Song::Song()
{
    title = "none";
    length = 0;
}

Song::~Song(void)
{
}

char* Song::getTitle() const
{
    return title;
}
double Song::getLength() const
{
    return length;
}
Song & Song::operator=(const Song & s)
{
    title = s.title;
    length = s.length;
    return *this;
}
bool & Song::operator==(const Song & s)
{
    bool result = false;
    if (title == s.title && length == s.length)
    {
        result = true;
    }
    return result;
}

我再次感谢尝试使代码更有效或更有意义,但我已经做了比老师要求我们更多的工作。我只是想知道是否有一个明显的原因,为什么在第一次报告显示之前删除该歌曲,即使报告在代码中排在第一位。

1 个答案:

答案 0 :(得分:1)

在不知道你的实现的情况下,很难回答你的问题,所以我按照我想象的那样写了它。不过,我做了一些改进:

  1. 3.14并不代表“3分14秒”。充其量,它意味着3.14分钟,即3分8.4秒。我已将其更改为明确的chrono原语
  2. 由于歌曲之间的不平等关系不明确,因此按值移除歌曲是不明确的。我注意到你已经超载了operator==,但我无法看到如何合理实施。为每首歌添加一个唯一的ID将是一种解决它的方法,但我觉得没有权利,所以我决定通过索引删除(这也很好地模拟了CD本身)。
  3. 集合不是线程安全的。别忘了。
  4. 我不知道为什么report是大写的,但我改变了这一点以保持一致性。
  5. 我不确定裁谈会内部的重组是如何运作的,所以我只是跳过那部分。


    #include <iostream>
    #include <list>
    #include <functional>
    #include <chrono>
    #include <string>
    #include <stdexcept>
    #include <iterator>
    
    // C++14-like shim
    // in C++14 just use min and s
    constexpr std::chrono::minutes operator "" _min(unsigned long long m) {
        return std::chrono::minutes(m);
    }
    constexpr std::chrono::seconds operator "" _s(unsigned long long s) {
        return std::chrono::seconds(s);
    }
    
    class Song {
    public:
        std::string title;
        std::chrono::seconds length;
    
        Song(std::string title, std::chrono::seconds length) :
            title(std::move(title)), length(length) { }
    };
    
    class Cd {
        std::list<std::reference_wrapper<Song>> songs;
        std::string performer, title;
    
    public:
        void addSong(Song & s) {
            songs.push_back(std::ref(s));
        }
        void removeSong(unsigned n) {
            if (n >= songs.size())
                throw std::out_of_range("The song of given index doesn't exist on that album");
    
            songs.erase(std::next(songs.begin(), n));
        }
        void report() const {
            std::cout << title << ", " << performer << '\n';
            for (auto const& song : songs) {
                std::cout << song.get().title << " " 
                          << song.get().length.count() / 60 << ":"
                          << song.get().length.count() % 60 << '\n';
            }
            std::cout << std::endl;
        }
    
        Cd(std::string performer, std::string title) :
            performer(std::move(performer)), title(std::move(title))
        { }
    };
    
    int main() {
        Song s1("Hey Jude", 4_min + 52_s);
        Song s2("The song of Pie", 3_min + 14_s);
    
        Cd c1 ("Beatles", "Capitol");
        c1.addSong(s1);
        c1.addSong(s2);
        c1.report();
    
        // this doesn't work anymore because of the reasons described above
        //c1.removeSong(s1);
        c1.removeSong(0);
        c1.report();
    }
    
相关问题