使用静态成员变量时出现链接器错误

问题描述 投票:0回答:3

我已经在这里浏览了与静态成员变量相关的所有线程,但不幸的是这无法帮助我找出原因。

这就是问题所在:

  1. 定义类名

    dvd_db
    。包括以下成员:

    数据成员:

    • DVD 名称 – 私有字符数组,大小 10
    • 价格 – 私有双变量
    • 数量 – 私有 int 变量
    • 一个私有静态 int 变量,用于跟踪到目前为止已创建了多少 DVD。

    会员功能:

    • 分配初始值
    • 设定价格和数量
    • 获取价格和数量
    • 打印 DVD
    • 显示到目前为止已创建了多少张 DVD。

在主函数中使用 DVD 阵列并演示 DVD 商店。即用户可以选择 DVD 并购买,
当 DVD 售出时,数量就会减少。

并且,我编写了这段代码来解决它。但在构建这段代码时遇到问题。编译器说对我使用

static
变量
cnt
的所有地方都未定义引用。还有一个问题,我想一开始将
cnt
设置为 0,既然它是私有变量,该怎么办?

如何解决未定义参考问题?

class dvd_db{

private:
    string name;
    float price;
    int quantity;
    static int cnt;

public:
    dvd_db()
    {
        name="";
        price=0;
        quantity=0;
        cnt++;  //to count the total number of dvds
    }

    dvd_db(string str,float p,int q)
    {
        name = str;
        price = p;
        quantity = q;
       // cnt=0;
        cnt+=q;
    }

    void set_name(string str)
    {
        name = str;
    }
    string get_name(void)
    {
        return name;
    }
    void set_price(float p)
    {
        price = p;
    }
    float get_price(void)
    {
        return price;
    }
    void set_quantity(int q)
    {
        quantity = q;
       cnt+=q;

    }
    int get_quantity(void)
    {
        return quantity;
    }
    void show_info(void)
    {
        cout<<"Name if the DVD: "<<name<<endl;
        cout<<"Price: "<<price<<endl;
        cout<<"Available Quantity: "<<quantity<<endl;
    }
    void total(void)
    {
        cout<<"Total number of dvd is: "<<cnt<<endl;
    }

    void buy(void)
    {
        if(quantity>0){
            quantity--;
            cnt--;
            cout<<"Thanks for purchasing this item"<<endl;
        }
        else
             cout<<"This Item can not be bought."<<endl;

    }
};
//dvd_db::cnt=0;

int main()
{
    dvd_db dvd[3];

    int i,j,k,n;

    dvd[0].set_name("A Beautiful Mind");
    dvd[0].set_price(50.00);
    dvd[0].set_quantity(10);

    dvd[1].set_name("October Sky");
    dvd[1].set_price(50.00);
    dvd[1].set_quantity(15);

    dvd[2].set_name("Shawshank Redemption");
    dvd[2].set_price(50.00);
    dvd[2].set_quantity(100);

    cout<<"Welcome to Banani International Movie House"<<endl;
    cout<<"Enter the serial no. to buy an item, -1 to view total no. of dvd(s), or enter 0 to quit."<<endl;
    cout<<"Here is our collection:"<<endl<<endl<<endl<<endl;

    for(i=0; i<3; i++){
        cout<<"serial no. "<<i+1<<endl;
        cout<<"------------------------------------"<<endl;
        dvd[i].show_info();

    }

    cout<<"Enter: "<<endl;

    while(cin>>n)
    {
        if(n==-1){
            dvd[0].total();
            cout<<"Enter: "<<endl;
            continue;
        }
        dvd[n-1].buy();
        cout<<"Enter: "<<endl;
    }
    return 0;
}
c++ class static
3个回答
2
投票

这么近!改变一下就好了

 //dvd_db::cnt=0;

致:

int dvd_db::cnt=0;

为什么?一个类有两部分:声明和定义。通常声明位于 .h 文件中,定义位于 .cpp 文件中。由于各种原因,cpp 还允许您将函数的定义放在声明中。正如您所做的那样,这对于单个文件示例来说很好。

但这对静态不起作用:静态只能有一个定义(根据定义,哈哈),而且它必须在声明之外。

在你的类声明中,你告诉任何查看它的人“有一个且只有一个 int cnt”。现在你还必须将该 int 放置在某个地方。这是在类声明之外完成的,并且只能完成一次。

每次实例化类时都会分配非静态成员,因此在创建类的实例之前它们不需要一个位置。函数介于两者之间,它们是代码,因此是只读的。因此编译器可以对它们进行智能处理。将它们放在类声明中可以让编译器在声明中看到它们并内联它们。但大的也应该放在声明之外。


1
投票

一个解决方案 - 已经在其他答案中提到 - 是添加一个 definition (一次,通常在 cpp 文件中):

int dvd_db::cnt = 0;

但是从c++17开始还有另一种解决方案:

static inline
:

静态数据成员可以声明为内联。内联静态数据 成员可以在类定义中定义,并且可以指定一个 初始化程序。它不需要类外定义

您可以替换类定义(H 文件中)中的 声明

  static int cnt;

与:

//vvvvvvvvvvvvv--------vvvv-
  static inline int cnt = 0;

这样您就不需要在 cpp 文件中单独定义。


0
投票

解决方案非常简单......对于静态变量,您需要在外部指定实例:

  class Foo {

  private:
         static int a;

  };

  int Foo::a = 0;

  int main() {
         Foo foo;
  }

因此,在您的情况下,您所需要做的就是取消注释该行 // dvd_db::cnt = 0;

并在它前面放一个int:

 int dvd_db::cnt = 0;

就是这样..您的链接问题将得到解决。

© www.soinside.com 2019 - 2024. All rights reserved.