You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++抽象类模板构造函数静态成员及MusicPlayer静态方法问题

题目背景

给定如下C++抽象类模板定义:

template <class MusicPlayer>
class SongAbstract {
 protected:
    unsigned long unique_id;
 public:
    SongAbstract() {
      static unsigned long counter = 0;
      unique_id = (counter++);
    }
    int play() const { return MusicPlayer::play(this->unique_id); }
    void stop() const { MusicPlayer::stop(); }
    unsigned long get_id() const { return unique_id; }
 protected:
    virtual void print_info(ostream& os) const = 0;
};

考题要求:根据上述代码实现MusicPlayer类,编写名为AndroidMusicPlayer的类声明使程序可正常运行。
官方给出的解决方案如下:

class AndroidMusicPlayer {
 public:
    static int play(unsigned long id);
    static void stop();
};
疑问解答
  • 针对第一个疑问:抽象类模板构造函数内部定义静态数据成员的作用是什么?
    构造函数内的static unsigned long counter是函数级静态变量,程序运行期间只会在第一次执行该构造函数时初始化一次,后续所有构造函数调用都会复用同一个counter变量。它的作用就是给每个创建的SongAbstract派生类对象分配全局唯一的unique_id标识,保证同系列歌曲对象不会出现ID重复的情况。这种写法不需要额外在类外声明全局计数变量或者类静态成员,封装性更优。另外需要注意,因为是类模板,不同MusicPlayer类型参数对应的SongAbstract实例会各自维护独立的counter,比如AndroidMusicPlayer对应的歌曲对象和IOSMusicPlayer对应的歌曲对象,计数是相互独立的。

  • 针对第二个疑问:AndroidMusicPlayer中的方法为什么要声明为static?它们访问的unique_id成员并不是静态的。
    首先看SongAbstract里的调用写法MusicPlayer::play(this->unique_id),这是C++调用静态类成员的标准语法,不需要创建MusicPlayer类的实例就能直接调用,所以要求对应的方法必须是静态的。
    另外你混淆了成员的访问逻辑:unique_id确实是SongAbstract对象的非静态成员,但它是作为入参传递给MusicPlayer::play方法的,不是MusicPlayer的方法直接访问SongAbstract的成员,所以两者的静态属性没有对应关系。
    这种设计也符合播放器的通用业务逻辑:整个系统只需要一个全局的播放器实例,所有歌曲的播放、停止控制都走同一个播放器处理,不需要每首歌单独创建播放器对象。

内容的提问来源于stack exchange,提问作者GalMichaeli

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 01:57:00