在C++;? < > C++中常被误解的概念是什么?< P>递减顺序: 确保释放分配内存的指针 何时析构函数应该是虚拟的 虚拟函数如何工作

在C++;? < > C++中常被误解的概念是什么?< P>递减顺序: 确保释放分配内存的指针 何时析构函数应该是虚拟的 虚拟函数如何工作,c++,C++,有趣的是,没有多少人知道虚拟函数的全部细节,但似乎仍然可以完成工作。指针 取消对指针的引用。通过或-> 需要指针时使用和的地址 通过在签名中指定&来引用参数的函数 指向指向指向指针的指针***或引用的指针void someFunc(int*&arg)以下是一些: 使用模板实现没有vtables的多态性,就像ATL一样 逻辑const-内存中的ness与实际const-内存中的ness。何时使用mutable关键字 致谢:谢谢你纠正我的错误 编辑: 以下是更多: 虚拟继承(不是虚拟方法):事实上

有趣的是,没有多少人知道虚拟函数的全部细节,但似乎仍然可以完成工作。

指针

取消对指针的引用。通过
->

需要指针时使用
的地址

通过在签名中指定
&
来引用参数的函数

指向指向指向指针的指针
***
或引用的指针
void someFunc(int*&arg)

以下是一些:

  • 使用模板实现没有vtables的多态性,就像ATL一样
  • 逻辑
    const
    -内存中的ness与实际
    const
    -内存中的ness。何时使用
    mutable
    关键字

  • 致谢:谢谢你纠正我的错误

    编辑:

    以下是更多:

  • 虚拟继承(不是虚拟方法):事实上,我一点也不懂!(我的意思是,我不知道它是如何实现的)
  • 其成员为对象的并集,其各自的类具有非平凡构造函数

  • 内存对齐。

    静态关键字,根据使用位置,它可以表示三种不同的内容之一

  • 它可以是静态成员函数或成员变量
  • 它可以是在命名空间范围内声明的静态变量或函数
  • 它可以是在函数中声明的静态变量

  • C++中的一个重要概念,经常被遗忘:

    C++不应该像对象一样简单地使用 面向对象的语言,如Java或C#。 从STL中启发自己,编写通用代码


    C++不是带类的C


    没有一种语言叫做C/C++。从那以后,一切都会走下坡路。

    赋值和初始化之间的区别:

    string s = "foo";    // initialisation
    s = "bar";           // assignment
    

    初始化总是使用构造函数,赋值总是使用运算符=

    有一些事情人们似乎经常感到困惑或不知道:

  • 指针,尤其是函数指针和多个指针(例如int(*)(void*)、void***)

  • const关键字和const正确性(例如,const char*、char*const和const char*const之间有什么区别,void class::member()const;的意思是什么?)

  • 内存分配(例如,应删除每个新指针,malloc/free不应与new/delete混合,何时使用delete[]而不是delete,为什么C函数仍然有用(例如expand(),realloc())

  • 作用域(即,您可以单独使用{}为变量名创建一个新的作用域,而不仅仅是作为if、for等的一部分)

  • Switch语句。(例如,不了解他们也可以(或在某些情况下更好)优化ifs链,不了解fall-through及其实际应用(例如循环展开)或存在默认情况)

  • 调用约定(例如,cdecl和stdcall之间有什么区别,如何实现pascal函数,为什么这很重要?)

  • 继承和多重继承,更一般地说,是整个OO范式

  • <> >内嵌汇编程序,如通常实现的,不是C++的一部分。


    < C++初学者的经典>:

    混淆
    delete
    delete[]

    编辑:

    使用C API时,所有经验级别中的另一个典型故障是:

    std::string helloString = "hello world";
    printf("%s\n", helloString);
    
    而不是:

    printf("%s\n", helloString.c_str());
    

    这每周都发生在我身上。您可以使用流,但有时必须处理类似printf的api。

    过度使用与多态性无关的继承。大多数情况下,除非您确实使用运行时多态性,否则组合或静态多态性(即模板)会更好。

    • 指向成员的指针和指向成员函数的指针
    • 非类型模板参数
    • 多重继承,特别是虚拟基类和共享基类对象
    • 构造和销毁顺序,中间函数类中间构造中虚函数的状态。
    • 铸造安全和可变尺寸。不,您不能假设可移植代码中的
      sizeof(void*)==sizeof(int)
      (或任何其他类型,除非可移植头特别保证)
    • 指针算法

    C++不是带字符串和向量的C

    • 当人们在C中创建静态变量时,匿名名称空间几乎总是真正需要的++
    • 制作库头文件时,pimpl习惯用法()应该用于几乎所有的私有函数和成员,以帮助进行依赖关系管理

    我所见过的最有害的概念是,它应该被视为带有一些插件的C。事实上,对于现代C++系统,它应该被看作是一种不同的语言,而我所看到的大多数C++攻击都是基于“C加上附加”模型。 提到一些问题:

    虽然您可能需要知道
    delete
    delete[]
    之间的区别,但通常您都不应该编写它们。使用智能指针和
    std::vector

    事实上,您应该很少使用
    *
    。对字符串使用std::string。(是的,它的设计很糟糕。无论如何都要使用它。)

    RAII意味着通常不必编写清理代码。清理代码的风格不好,会破坏概念上的局部性。作为奖励,使用RAII(包括智能指针)可以免费为您提供许多基本的异常安全性。总的来说,它在某些方面比垃圾收集好得多

    通常,类数据成员
    int x = sizeof(char);
    
    // C++
    void DoSomething()
    {
      File file("/tmp/dosomething", "rb");
      ... do stuff with file...
      // file is automatically free'ed and closed.
    }
    
    // C#
    public void DoSomething()
    {
      File file = new File("/tmp/dosomething", "rb");
      ... do stuff with file...
    
      // file is NOT automatically closed.
      // What if the caller calls DoSomething() in a tight loop?
      // C# requires you to be aware of the implementation of the File class
      // and forces you to accommodate, thus voiding implementation-hiding
      // principles.
      // Approaches may include:
      // 1) Utilizing the IDisposable pattern.
      // 2) Utilizing try-finally guards, which quickly gets messy.
      // 3) The nagging doubt that you've forgotten something /somewhere/ in your
      //    1 million loc project.
      // 4) The realization that point #3 can not be fixed by fixing the File
      //    class.
    }