代码之家  ›  专栏  ›  技术社区  ›  Tomas

C++空指针

  •  3
  • Tomas  · 技术社区  · 14 年前

    我在想,为什么不能有一个不是指针的空数据类型?

    当然你可以通过

    void4
    void8
    void32
    

    然后只允许将一个空数据类型“强制”到另一个类,如果它的大小等于或小于类的大小。

    有什么我错过了,还是C++委员会认为它不好的练习?

    我还没有很好地解释自己,所以我将举一个使用它的例子:

     main()
    {
        /* 
    
         Lets make a list of unknown elements
    
         std::string is 8 bytes, and float is 4
         bytes, so we'll reserve 8 byte sequences
    
         */
    
        vector<void8> elements;
    
        elements.push_back((void8) string("First string element"));
    
        elements.push_back((void8) float(5.76) );
    
        elements.push_back((void8) string("Third string element"));
    
        // Ect.
    
        cout << (string) elements[0];
        cout << (float) elements[1];
        cout << (string) elements[2];
        cout << (float) elements[2]; // Garbage
    
    
        void1 data;
    
        data = (void1) bool(1);
        data = (void1) unsigned int(80094); // Error, not enough size
    }
    

    它被命名为void,因为您不知道它当前存储的是什么类型,类似于void指针。

    10 回复  |  直到 14 年前
        1
  •  3
  •   Mike Seymour    14 年前

    在强类型语言中,所有数据都有一个类型,因此不存在“void”作为数据类型的概念。在C和C++中,它的含义是“无数据”(作为返回值),或者“不知道类型的数据”(作为指针目标)。

    您提出的中间状态是“您不知道其类型但知道其大小的数据”,可能是您通过值传递的类型的不透明版本。除了这是一件相当危险的事情(因为在更改实际类型的大小时必须使用不透明类型手动更新所有代码)之外,还可以在不向语言添加奇怪扩展的情况下完成这项工作,例如:

    struct void8 { char bytes[8]; };
    

    这个 能够 reinterpret_cast 像你建议的那样,把豆荚类型作为不透明的团块传递。将它与非POD类型一起使用比使用 void* 指非吊舱类型。

    boost::any 如果你想要值语义。很少有必要使用“空隙”作为C++中的占位符类型。

        2
  •  8
  •   Puppy    14 年前

        3
  •  2
  •   alxx    14 年前

    什么是空虚?什么都不是,空虚。嘿,哈哈! void用于指定不返回任何内容的函数。在其他语言中有关键字“procedure”或“sub”。指向void的指针是指向unknown的指针(void的第二个用法)。这是两个目的。

    更新:我想,作者想用已知的大小指定未知类型。void32*是指向某个大小为32位的实体的指针,void8*是指向8位实体的指针,依此类推。但是它很容易用int32*,char*模拟,而不需要语言扩展。

        4
  •  2
  •   Stack Overflow is garbage    14 年前

    你要找的东西已经存在了。它被称为 char 烧焦 可用于将未知对象存储到,因为 烧焦 基本上是C++的字节名称。因此,要将未知或可变类型的对象存储到单个数组中,需要使用字节数组,而不是空数组,这 void

    关键点 无效 关键是我们没有 void4 没什么意义。如果我们知道物体的大小,它就不再是“空的”。我们能做的唯一一件事就是指向一个未知的物体。我们不能将它存储在任何地方,因为我们不知道它是否是一个POD对象,也不知道它有多大,或者它的对齐要求。所以我们肯定不会把它存储到数组中。我们所能做的就是创建一个指向它的指针,我们已经有了 无效 这方面的指针。

    当然,还有一个有趣的小问题:

    这里的T型是什么?

    void foo(void* p) {
       T q = *p;
    }
    

    空隙4 ? void32 ? 或者只是 无效 ? 这个物体应该有多大?我们知道些什么?是豆荚型的吗?

        5
  •  2
  •   Oliver Charlesworth    14 年前

    “void”数据类型的含义是什么?我不认为有一个有效的,所以这可能是它不存在的原因。

        6
  •  0
  •   ckv    14 年前

    我猜您指的是一个数据类型,它的功能可能类似于void类型,但您可能希望更改名称,而不是将其称为void。

        7
  •  0
  •   Potatoswatter    14 年前

    void* 不是指针 无效的,无效的。是指针

    void 它本身是由缺乏价值来定义的。它的表示中没有位。它不能形成对象。

    你所描述的东西可以从中转换。因此它包含信息。因此,它不是一个空洞。

    你所描述的只是一个简单的例子 int 其中忽略数值。但建议的用途是拙劣的做法。

        8
  •  0
  •   Michael Ekstrand    14 年前

    void 是“unhabited”类型,这意味着没有可能的类型值 无效 无效 价值观将毫无意义。

    退一步:C和C++相当一致地认识 意思是“什么都没有”。可以有一个指向nothing的指针,并使用它来携带指向某个对象的指针的值,但不能取消对它的引用- 无效 没有任何价值,你可以做任何事。

    同时请注意 -对于void指针的情况,没有什么是可以实现的:而一些编译器(如GNU)允许您对其执行指针运算 void* 价值观 char* ,标准禁止在 无效* 无效

    所以,我认为答案是:这将是毫无意义的。 无效 是nothing,并且不能在值中存储nothing。

        9
  •  0
  •   BitShifter    14 年前

    我想你应该看看工会。联合体保留足够的空间来容纳联合体中最大的成员,然后根据您引用联合体的方式,选择“适当”的空间量,并根据您请求的类型将其提供给您。

    也就是说,就像将一个字符数组转换为实际要查找的类型一样,在使用这种功能之前,您应该仔细考虑。

        10
  •  0
  •   adrianm    14 年前

    如果有一个空的数据类型,我认为它应该不代表任何东西,只是吞下存储在其中的任何东西。

    你可以说

    (void)func1();
    

    void x;
    x = func1();
    

    void func2() {
       void x;
       ...
       return x;
    }
    

    和作为函数参数

    int func3(int x, void y, char z);
    
    void x = func3(1,2);
    x = func3(1,x,2);
    

    我可以在一些模板编码中看到这种用法。