【发布时间】:2017-10-18 12:24:45
【问题描述】:
所以昨天我正在寻找 SO 并找不到以下问题的答案。这种情况来自我正在使用的一些代码,但这里是演示它的 MCVE。
我在 A.h 中定义了一个类 A,其中只有一个静态常量。我已经在标题中初始化了它。
#ifndef A_H_
#define A_H_
class A {
public:
static const int test = 5;
~A(){};
};
#endif /* A_H_ */
然后我有一个 B 类,它需要从 A 类访问公共静态常量。在这个例子中,它会将值深度复制到一个向量。
#ifndef B_H_
#define B_H_
#include "A.h"
#include <vector>
#include <iostream>
class B {
private:
std::vector<int> testVec;
public:
B(){
testVec.push_back((const int)A::test);
//testVec.push_back(static_cast<const int>(A::test)); //Also works
//testVec.push_back(A::test); //Doesn't work without forward declaration of const int A::test in main or in this header
//(Compiler link error: undefined reference to `A::test')
std::cout<< testVec.front() << std::endl;
}
~B(){};
};
#endif /* B_H_ */
然后在main中我简单地调用B类的构造函数。
#include "B.h"
int main() {
B b;
return 0;
}
//Does the cout from ctor of B and prints 5 to the screen.
我的问题是为什么普通强制转换或静态强制转换允许我访问这个尚未前向声明的静态 const 变量。在普通代码中,我会转发声明变量或将其声明为 extern,因为它已经被定义了。为什么强制转换允许我在没有前向声明的情况下访问这个变量的原因是什么? (这似乎是一个简单的问题,可能有一个简单的答案,但我想在这里进一步了解我的知识)。
编译器链接错误的输出是:
Invoking: Cygwin C++ Linker
g++ -o "S_Test_p1.exe" ./src/S_Test_p1.o
./src/S_Test_p1.o:S_Test_p1.cpp:(.rdata$.refptr._ZN1A4testE[.refptr._ZN1A4testE]+0x0): undefined reference to `A::test'
collect2: error: ld returned 1 exit status
make: *** [makefile:47: S_Test_p1.exe] Error 1
我的主要问题是为什么强制转换有效,而不是解决方案是在 main 或 B.h 中定义 A::test (我知道这是有效的)。我明白这将被接受和适当的。主要问题是关于不被接受的方式,即铸造。在幕后,为什么投射对链接有效?
【问题讨论】:
-
为什么
testVec.push_back(A::test);不起作用?它应该... -
@Rene 因为静态应该在某处定义并存储在某处
-
@Rene 它不会链接,我已经用我的嵌入式系统的 MULTI 编译器和 Cygwin GCC 尝试了这个。输出:对 `A::test' 的未定义引用
-
别告诉我。我希望 OP 发布他得到的错误,这样我们就可以解决这个错误。然而,演员表不是正确的解决方案。
-
@Rene 我知道解决方案是前向声明,并且它将与它相关联。但为什么演员阵容有效?这是我的问题。