我似乎对C ++中的`static`有一些误解

时间:2014-03-24 09:07:15

标签: c++ static

我似乎对static关键字在C ++中的工作原理有一些误解;具体来说,我需要通过以下代码了解问题:

#include <iostream>

struct A{
    int a;

    A(int ain) : a(ain) { }
    A() : a(1) { }

    static A getA()
    {
        return A(2);
    }
};

struct B
{
    static A a = A::getA();
};


int main() {
    std::cout << B::a.a << std::endl;
}

如果static按预期工作,上面的代码示例将打印2并正常退出 - 相反,我得到以下编译器错误消息:

g++    -c -o syntax.o syntax.cpp
syntax.cpp:17:21: error: ‘A::getA()’ cannot appear in a constant-expression
     static A a = A::getA();
                     ^
syntax.cpp:17:26: error: a function call cannot appear in a constant-expression
     static A a = A::getA();
                          ^
syntax.cpp:17:26: error: invalid in-class initialization of static data member of non-integral type ‘A’
syntax.cpp:17:26: error: initializer invalid for static member with constructor
syntax.cpp:17:26: error: (an out of class initialization is required)
syntax.cpp:17:26: error: ‘B::a’ cannot be initialized by a non-constant expression when being declared
make: *** [syntax.o] Error 1

我阅读了错误消息,并且我发现有一些关于static的内容我还没有理解,但我发现很难确定是什么。这可能是因为我在Java和C#等语言中做了相当多的工作,这些语言也有static关键字,但显然它的工作方式不同。

请有人向我解释为何上述代码无效?

3 个答案:

答案 0 :(得分:4)

静态会员功能

有两种方法可以调用给定T静态成员函数;

  • 您使用scope resolution operator ::或;

  • 您使用T在所述类型operator.的实例上调用它(就像您在变量上调用任何其他成员函数一样)。 / p>


法律架构

struct Obj {
  static void func () { 
    /* ... */
  }
};

下面的两个片段都在func内调用静态成员函数Obj

Obj a; a.func ();

Obj::func ();


ILLEGAL CONSTRUCTS

Obj a;

Obj.func (); // illegal, `Obj` is a type and not an instance
a ::func ();  // illegal, `a` is an instance of `Obj`, not a type


静态数据成员

static数据成员用于声明在给定类型的每个实例之间共享的变量。

在问题中提供的代码段中,您尝试初始化类型为a的静态数据成员A,其中包含已更正的值A::getA ()。这是不允许的,因为尝试初始化static数据成员而不使其constexpr是用于类内初始化的非法构造。

struct B {
  static A a = A::getA(); // illegal, `static A a` is not `constexpr`
};

可以在此处找到有关静态数据成员的类内初始化的更多信息:

答案 1 :(得分:3)

有两个问题。首先,语法A.getA()是错误的:.语法用于访问实例的成员。您不能使用它通过类型访问成员。要使用.运算符,您必须创建A的实例,并通过该实例调用getA()。但这没有任何意义。所以你需要做的是使用类范围分辨率调用方法,即A::getA()。这是第一个问题。

第二个是你不能在声明点定义一个非const,非整数的静态成员。您必须将声明定义分开。后者应该只在一个翻译单元中,这意味着将它放在一个.cpp文件中:

标题文件:

struct B
{
    static A a; // declaration
};

实施档案

A B::a = A::getA(); // definition

答案 2 :(得分:1)

您使用语法调用实例函数,您需要使用scope resolution operator ::语法:

A::getA();