如果我只在类内部使用类变量,为什么要在类外部创建类变量的定义呢?

Why have I to create the definition of the class variables out of the class, if I use them only inside?

本文关键字:类变量 创建 外部 定义 为什么 内部 如果      更新时间:2023-10-16

尝试创建一个小测试,我遇到了一个问题

#include "stdafx.h"
#include "CppUnitTest.h"
#include "CppUnitTestAssert.h"
using namespace Microsoft::VisualStudio::CppUnitTestFramework;
namespace SprintfTestNamespace
{       
    TEST_CLASS(SprintfTest)
    {
    public:
        static char output[100];
        static const char * expected;
        TEST_METHOD_INITIALIZE(SprintfTestInit)
        {
            memset(output, 0xaa, sizeof output);
            SprintfTest::expected = "";
        }
        static void expect(const char * s)
        {
            expected = s;
        }
        static void given(int charsWritten)
        {
            Assert::AreEqual((int)strlen(expected), charsWritten,
                L"result string length ");
            Assert::AreEqual(expected, output, false,
                L"result string content ");
            Assert::AreEqual((char)0xaa, output[strlen(expected) + 1],
                L"meaning of the first outer char after string");
        }
        TEST_METHOD(NoFormatOperations)
        {
            expect("hey");
            given(sprintf(output, "hey"));
        }
        TEST_METHOD(InsertString)
        {
            expect("Hello Worldn");
            given(sprintf(output, "Hello %sn", "World"));
        }
    };
    char SprintfTest::output[100];      // notice these two lines!
    const char* SprintfTest::expected;
}

如果我删除最后的两个标记行,我得到错误LNK2001:

未解析的外部符号"public: static char * SprintfTestNamespace::SprintfTest::output" (?output@SprintfTest@ sprintftestnamespace@2pada)

如果我有他们的地方,一切工作正常,它构建和链接和测试。但是,如果我只在类内使用类变量,为什么我要在类外定义它们呢?

您没有在类外声明它们。您正在在类外定义它们。在c++中,作为左值使用的对象需要一个定义,这实际上是为该对象保留存储空间(内存)。对于静态类成员,可以通过在类外定义这样的对象来保留内存。

类内部的只是这些静态成员的非定义性声明。为这些声明提供定义是您的责任。当您忘记定义您声明的东西时,您将从链接器获得"未解析的外部符号…"错误,这正是您的情况所发生的。

请注意,为了满足一个定义规则,这些定义通常应该进入单个实现文件(.cpp文件)。你不应该把这样的定义放在头文件中。

c++中唯一的例外是某些类型的静态成员,它们在代码中不用作左值,因此不需要为这些成员分配内存。