As funções de membro estáticas podem ser declaradas como const?
Não posso. A função de membro estático pertence à classe e pode ser acessada diretamente pelo nome da classe. Ela não pertence a nenhum objeto e o ponteiro this não será colocado no acesso.
No entanto, funções-membro const adicionarão um const this * implícito quando acessadas e seu uso é conflitante.
As funções de membro estático podem ser declaradas virtuais?
Não posso. As funções de membro estáticas têm apenas um código para cada classe e não há necessidade de ligação polimórfica.
Por que C ++ não oferece suporte ao construtor como uma função virtual?
A função virtual é acessada por meio do ponteiro virtual vptr, que é inicializado por meio do construtor. Se o construtor for uma função virtual, o que significa que vptr não pode ser gerado, ele cairá em um paradoxo.
http://legendtkl.com/2014/09/30/cplusplus-static-and-virtual/
Primeiramente, deixe-me declarar que este não é um tutorial introdutório, desde que você entenda a função da estática e o mecanismo de implementação de funções virtuais em C ++. :)
Deixe-me começar com algumas perguntas. Pense um pouco. O destruidor de uma classe pode ser virtual? O construtor de uma classe pode ser virtual? O construtor de uma classe pode ser estático? O destruidor de uma classe pode ser estático? As funções virtuais podem ser estáticas?
A função da palavra-chave estática pode ser simplesmente resumida como: quando aplicada a variáveis globais, quando aplicada a variáveis locais, quando aplicada a funções e quando aplicada a classes em C ++. Existem muitos dos três primeiros tipos de escrita. Hoje, escrevo principalmente quando a estática é aplicada a classes C ++, bem como palavras-chave virtuais.
O uso de estático em classes é simplesmente de dois tipos: membros de dados estáticos e funções de membro estático.
O membro de dados estáticos é proposto pelo compilador e pela classe e é considerado uma variável global, mas apenas visível no escopo de vida da classe. Cada membro de dados estáticos possui apenas uma entidade, que é armazenada no segmento de dados do programa. Você pode usar static para modificar variáveis locais para comparação e compreensão. Embora o acesso possa ser chamado pelo operador '.', Não é necessário, ou seja, pode ser chamado pelo operador de escopo "::". Por exemplo, a classe A possui um membro de dados estáticos z que pode ser chamado por A :: z. É importante notar que os membros de dados estáticos da classe devem ser definidos globalmente antes que possam ser usados. Caso contrário, o compilador reportará um erro: referência indefinida. Em outras palavras, membros estáticos são declarados na classe e são invisíveis de fora.
Antes de falar sobre funções de membro estáticas, vamos falar sobre como chamar funções de membro. Vamos falar sobre funções de membro não estáticas primeiro. Para garantir que as funções de membro não estáticas sejam pelo menos tão eficientes quanto as funções externas gerais, o compilador reescreverá funções de membro não estáticas em funções gerais. As principais etapas de conversão são as seguintes:
- Reescreva o protótipo da função e insira um parâmetro adicional neste ponteiro para fornecer um canal de acesso para o objeto de classe chamar a função.
- As operações de acesso a membros de dados não estáticos da classe no corpo da função são alteradas para acesso por meio do ponteiro this.
- Reescreva a função de membro como uma função externa e "mutile" o nome da função para evitar conflitos de símbolo.
Um exemplo é o seguinte:1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
class Legend { private : int x; int y; int z; public : legend () {} ~ legend () {} int sum () const { int ret = x + y + z; return ret; } }; // 内部 转化void sum_3legendFv ( const legenda * const this , int & amp; __ result) { int ret = this - & gt; x + this - & gt; y + this - & gt; z; __resultado = certo; return; }
感受一下思想,其中引入了NRV(named returned value),先不要太在意,知道有这个东西就好了。
虚成员函数是通过虚函数表来访问的。虚函数的实现机制简单来说就是,类为所有的虚函数建一个虚函数表vtbl,每个类只有一个。每个对象有一个虚函数表指针,vptr,通过指针来访问。因为访问说到底就是找到函数地址。之所以多态无法在编译器间确定,而要在运行时才能确定就是因为在编译器无法确定指针或者引用指向的真正的类型,从而无法确定偏移找到函数地址。
1 2 3 |
prt->normal() //内部转化 (*ptr->vptr[1])(ptr) |
其中vptr表示由编译器产生的指针,指向virtual table。1是virtual table slot的索引值,关联到normal函数,第二个ptr是this指针。
静态成员函数并不会关联到this指针,因此差不多等同于外部函数。主要有下面三个特性
- 不能直接存取其class内的非静态成员
- 不能够直接声明为const
- 不需要通过对象来调用。
下面我们来看上面几个问题
1.类的析构函数可以为virtual吗?毋庸置疑,对于可能作为基类的类的析构函数要求就是virtual的。因为如果不是virtual的,派生类析构的时候调用的是基类的析构函数,而基类的析构函数只要对基类部分进行析构,从而可能导致派生类部分出现内存泄漏问题。
2.类的构造函数可以为virtual吗?答案也是不能的,通过上面虚函数的调用方式我们知道虚函数是通过vptr来访问的。那么vptr是怎么来的呢?vptr确定通过构造函数来初始化的。鸡生蛋,蛋生鸡,鸡生蛋……
3.类的构造函数可以为static吗?根据之前说的static不能访问非静态成员变量这点可以知道构造函数是不可以为static的。两者static是对应于每个类的,而构造函数主要负责初始化对象的。这里要提一下C#中的static构造函数是用于在使用类之前进行相关的初始化工作。比如,初始化静态成员或执行特定操作。CLR在第一次创建该类对象或调用该类静态方法时自动调用静态构造函数。
4.类的析构函数可以为static吗?同上。
5.virtual函数可以为static吗?答案是不可以。virtual函数和static函数访问方式是不一样。
http://blog.csdn.net/love_gaohz/article/details/7534140
inline, static, constructor三种函数都不能带有virtual关键字。