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

C++ Class Method Running before other Method

本文关键字:类方法 运行 其他 方法      更新时间:2023-10-16

我过去已经使用了大量使用此站点,并且从来没有实际发布一个问题,但是我不确定如何简单地表达这个问题。我在Devry的C 课程中,我项目的实际作业需求方面已经完成,但我正在添加一些练习元素。

为了进行家庭作业,我添加了一个名为Song的其他课程。它具有2个私人变量(标题和长度),一些基本的构造函数和= ==的操作过载。一切都很好。然后,我在CD类中添加了歌曲类数组(每张CD最大歌曲为10)。我为CD创建了一些新方法:

  • Addsong(Song S);
  • Removesong(Song S);
  • 组织();和
  • 修改后的报告()const;

根据选择的数量来按顺序写出歌曲。CD的选择和游戏时间的私人价值现在分别与歌曲的总数和这些歌曲的总长度有关。一切都很好。Removesong将指定的歌曲从列表中取出,然后将组织召集到阵列中最低的值。但是,无论我在哪里称呼resmovesong(Song s)的任何地方,都可以在任何内容写入该程序之前将其删除。因此,以下代码将从CD中汲取信息,但是尽管在报告方法之后调用了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之前会影响报告的输出。我已经测试了不同的方法和过载,并且它们都按照预期工作,这是我感兴趣的时机的时间。很快:在调用第一个报告之前。(为了一致性,我确实需要更改报告中的大写)。我大多确定这是我错过的基本内容。

主代码:

// 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. 3.14并不意味着" 3分钟14秒"。充其量是3.14分钟,即3分钟8.4秒。我将其更改为明确的chrono原语
  2. 由于歌曲之间不清楚的平等关系,以价值删除歌曲是模棱两可的。我注意到您已经超载了operator==,但是我看不到如何合理地实现这一目标。在每首歌曲中添加独特的ID将是一种解决它的方法,但我没有资格,因此我通过索引删除了(这也很好地建模CD本身)。
  3. 集合不是线程安全。不要忘记这一点。
  4. 我不知道report为什么是大写,但我将其更改为保持一致性。

我不确定CD内部的重组如何工作,所以我只是跳过了那部分。


#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();
}