C++ 双冒号混淆

C++ 双冒号混淆,c++,C++,为什么我可以在未定义的函数和类中使用双冒号,但不能在变量中使用 例如: #include <iostream> using namespace std; class Person{ public: int age; string name(); }; int Person::age = 10; //It outputs an error string Person::name(){ //It doesn't return "n

为什么我可以在未定义的函数和类中使用双冒号,但不能在变量中使用

例如:

#include <iostream>

using namespace std;

class Person{

    public:
        int age;
        string name();
};

int Person::age = 10; //It outputs an error

string Person::name(){ //It doesn't
    return "n";
}
#包括
使用名称空间std;
班主任{
公众:
智力年龄;
字符串名();
};
整数人:年龄=10岁//它输出一个错误
字符串Person::name(){//它没有
返回“n”;
}
为什么我可以在未定义的函数和类中使用双冒号,但不能在变量中使用

age
是一个实例字段,它存在于内存中的多个位置-每个
人都有一个

现在,我将详细介绍
操作符的作用、如何使用它,以及
静态
类成员与实例成员的比较:

运算符:
(The)在C++中有多种用途:

如果您熟悉java、C++或JavaScript,则可以将其比作点引用或“导航操作符”<代码> .<代码>(例如:代码>命名空间.class .Mult.方法().结果< <代码> > -除C++之外,对于不同类型的导航和撤销使用不同的操作符:

  • 成员访问操作符,与C类似-它仅适用于“对象值”和引用(
    foo&
    ),而不适用于指针(
    foo*
  • ->
    是指针类型的另一个成员访问操作符,请注意,此操作符可以被覆盖,但
    不能(覆盖
    ->
    有风险,但如果操作正确,可改善智能指针库的人体工程学)
  • 范围解析运算符-它有一些不同的用途:
    • 命名空间导航-而java和C++则使用<代码> ./COD>来浏览包和命名空间,C++使用 >::/COD>,例如::使用STD::Time< /Cal>
    • 当不合格时,它还用于引用全局名称空间,例如
      ::std
      ,如果您正在编写已在名称空间中的代码,这将非常方便
    • 它还用于访问类型的静态成员-通常是实际的
      静态成员(静态方法或字段),但也可以访问
      枚举类
      (作用域枚举)值之类的项(例如
      SomeEnumClass::value\u name
    • 最后,在处理<>代码>虚拟< /Cord>方法实现时,也使用了一种特定的基本方法:当重写方法需要调用一个超类-C++中的基本实现时,没有C(c)和java(分别)的奇异代码< >基础<代码> >或<代码>超级< /C> >关键字。因为C++允许多重继承,所以必须指定特定的父类名称:
无论如何,在您的例子中,您似乎对实例和静态成员的实际含义感到困惑,因此下面是一个示例:

class Person {
public:
    int height; // each Person has their own height, so this is an instance member
    static int averageHeight; // but an individual Person doesn't have an "average height" - but a single average-height value can be used for all Persons, so this is a shared ("static") value.

    int getAverageHeight() { // this is an instance method, btw
        return Person::averageHeight; // use `Person::` to unambiguously reference a static member of `Person`
    }

    Person()
    : height(0) {
        // instance members should be initialized in the constructor!
    }
}

// This will create an array of 10 people (10 different object instances).
// Each Person object (an instance) will have its own `height` in memory
Person* multiplePeople = new Person[10];

// btw, you probably should use `std::array` with an initializer instead:
// array<Person,10> multiplePeople{}; // <-- like this

// This sets a value to the `staticField` member, which exists only once in memory, that is, all Person instances share the same value for this member...
Person::averageHeight = 175; // 175cm

// ...for example:
assert( 175 == multiplePeople[3]->getAverageHeight() );
assert( 175 == multiplePeople[6]->getAverageHeight() );

// However instance members can have different values for each instance:
multiplePeople[3]->height = 170;
multiplePeople[6]->height = 180;

// Btw `height` is initialized to 0 in each Person's constructor.
assert( 170 != multiplePeople[0]->height );
assert( 180 != multiplePeople[7]->height );
班级人员{
公众:
int height;//每个人都有自己的身高,因此这是一个实例成员
static int averageHeight;//但是一个人没有“平均身高”——但是一个平均身高值可以用于所有人,因此这是一个共享(“静态”)值。
int getAverageHeight(){//这是一个实例方法,顺便说一句
return Person::averageHeight;//使用`Person:::`明确引用`Person'的静态成员`
}
人()
:高度(0){
//实例成员应该在构造函数中初始化!
}
}
//这将创建一个10人的数组(10个不同的对象实例)。
//每个Person对象(一个实例)在内存中都有自己的“height”
人员*多人=新人员[10];
//顺便说一句,您可能应该将'std::array'与初始值设定项一起使用:
//数组多人{};//getAverageHeight());
断言(175==multiplePeople[6]->getAverageHeight());
//但是,对于每个实例,实例成员可以具有不同的值:
多人[3]->身高=170;
多人[6]->身高=180;
//顺便说一句,在每个人的构造函数中,“height”被初始化为0。
断言(170!=多人[0]->高度);
断言(180!=多人[7]->高度);

为什么您认为这应该有效?我建议你选择一个。如果你把年龄设为静态,那么它就会工作。它会是,@JerryJeremiah,还是只是编译?作品和汇编之间的巨大差异。@CaptainObvlious可能是因为我还在学习??我仍然对C++有一种非常盲目的看法。Dormin Meh,通过猜测学习不是C++的方式,这太奇怪了。真的读了C++的书。你的答案为我解决了一个以上的问题,我真的很感激!^ ^Vladfrommoskow他的问题是关于
操作符的背景和使用-你认为我为什么没有正确回答他的问题?@Dai操作符也可以用于非静态数据成员。