二义性

虚拟继承解决二义性及数据冗余的原理

橙三吉。 提交于 2020-03-14 12:30:34
虚拟继承的原理 虚拟继承解决数据冗余和二义性的奥秘就在于,它在继承之后并不会创造出两个基类成员给派生类各自继承,而是在派生类中记录两个偏移量,大小为从派生类中继承的基类成员的地址到真正的基类成员地址,而这个真正的成员,被放在最后一次继承的派生类(D类)的末尾。 如图所示,在不使用虚拟继承的前提下,各个类定义定义变量后我们可以看看他们各自所处的地址如下: 可以看出,A,B类继承的m_n处于不同的地址,是两个成员。而使用虚拟继承后他们所处地址的内容变成了如下: 可以看出,原本为值‘3’和‘4’的地方变成了两个偏移量,而我们调取这两个偏移量之后可以看到如下: e8 d2 f5 00 :12(H) ac cb f5 00 :20(H) 而我们发现,从起始位置到下面04的位置(D类中的末尾),偏移字节正好是12和20。 其实, 这里是通过B和C的两个指针,指向一张表,这两个指针叫做虚基表指针,这两个表叫虚基表,虚基表中存的偏移量,通过偏移量可以找到下面的A。 Ps:并不是所有派生类共用一分虚基表,每个派生类都有自己的表; 来源: 51CTO 作者: wx5cb188ffabeef 链接: https://blog.51cto.com/14289397/2478237

C++多重继承二义性解决

邮差的信 提交于 2020-02-13 00:25:56
1. 什么是多重继承的二义性 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 class A{ public : void f(); } class B{ public : void f(); void g(); } class C: public A, public B{ public : void g(); void h(); }; 如果声明:C c1,则c1.f();具有二义性,而c1.g();无二义性(同名覆盖)。 2. 解决办法一 -- 类名限定 调用时指名调用的是哪个类的函数,如 1 2 c1.A::f(); c1.B::f(); 3. 解决办法二 -- 同名覆盖 在C中声明一个同名函数,该函数根据需要内部调用A的f或者是B的f。如 1 2 3 4 5 6 7 8 class C: public A, public B{ public : void g(); void h(); void f(){ A::f(); } }; 4. 解决办法三 -- 虚基类(用于有共同基类的场合) virtual 修饰说明基类,如: 1 class B1: virtual public B 虚基类主要用来解决多继承时,可能对同一基类继承继承多次从而产生的二义性。为最远的派生类提供唯一的基类成员,而不重复产生多次拷贝。注意

LEX和YACC的使用三

我是研究僧i 提交于 2020-01-21 03:27:52
2.4.3 yacc解决二义性和冲突的方法 在2.3.8中已涉及到二义性和冲突的问题,这里再集中介绍一下,这在写Yacc源程序时会经常碰到。二义性会带来冲突。在2.3.8中我们介绍了yacc可以用为算符确定优先级和结合规则解决由二义性造成的冲突,但是有一些由二义性造成的冲突不易通过优先级方法解决, 如有名的例子: stat:IF bexp THEN stat |IF bexp THEN stat ELSE stat ; 对于这样的二义性造成的冲突和一些不是由二义性造成的冲突,Yacc提供了下面两条消除二义性的规则: A1.出现移进/归约冲突时,进行移进; A2. 出现归约/归约冲突时,按照产生式在yacc源程序中出现的次序,用先出现的产生式归约。 我们可以看出用这两条规则解决上面的IF语句二义性问题是合乎我们需要的。所以用户不必将上述文法改造成无二义性的。当Yacc用上述两条规则消除了二义性,它将给出相应信息。 下面再稍微严格地介绍一下Yacc如何利用优先级和结合性来解决冲突的。 Yacc源程序中的产生式也有一个优先级和结合性.这个优先级和结合性就是该产生式右部最后一个终结符或文字字符的优先级和结合性,当使用了%Prec子句时,该产生式的优先级和结合性由%Prec子句决定。当然如果产生式右部最后一个终结符或文字字符没有优先级或结合性,则该产生式也没有优先级或结合性。 根据终结符

C++存在二义性的问题

馋奶兔 提交于 2020-01-03 10:36:59
一、什么是二义性 在多继承的场景里,当父类中存在同名变量时,子类访问父类的同名变量,将出现二义性,因为编译器不知道你将要访问的是哪个父类中的变量。 举个例子: class A { public: int a; // B1,B2 都将继承一个变量 a }; class B1 : public A { }; class B2 : public A { }; class C : public B1, public B2 { }; int main() { C c; c.a = 10; // ERROR ! 二义性 !!! return 0; } 二、怎么解决 不使用多继承 一般来说,单继承就可以满足我们 99% 的需求了,我们应该尽量避免使用多继承带来的二义性问题。(注意:这里说的单继承不包括下面说的这种类似于 “接口” 的父类)。 由于 C++ 中不存在接口,但是可以使用只包含纯虚函数的抽象类替代,如果是只包含纯虚函数的抽象类,再多继承都将不会发生二义性(父类都没有变量了当然不会有二义性)。 使用虚继承 虚继承只能解决多个父类的同名变量都是从公共基类中继承而来的情况,就是下图这种: 使用虚继承: class A { public: int a; }; class B1 : virtual public A // 虚继承 { }; class B2 : virtual public A

侃一侃编译原理的“文法”

落花浮王杯 提交于 2019-12-22 02:30:10
如果你敲累了代码,想喝喝咖啡,顺便看点儿可以当佐料的文章那本文应该比较适合现在的你。(•̀ᴗ•́)و ̑̑ 我们一天天都在和代码打交道,但是你了解代码的运行原理么?为什么你的一行代码就能被执行出五花八门的效果嘞? 其实代码这玩意儿就是一门语言。是的,你可以看成和中文、英文等语言平等的存在。是语言就得有语言的解析规则,不懂得规则自然无法理解语言的意思。就跟看没字幕的美剧一样,真是痛苦。╮(╯﹏╰)╭ 中文有中文的语义、语法、句子、句法、文法,那么编程语言也有自己的语言系统。 我们知道,我们写的代码被编译器或者解释器所执行,那它们是按照什么文法来理解你的代码呢?这就是文法。 本文也不会深入去解析文法,不然可以直接转语言学了(笑~)。本文只是简单介绍文法的一些概念。如果您喝着咖啡,看完之后,能有些许收获,微微一笑,那本文的目的也就达到了。^_^ 工欲善其事必先利其器。在谈文法之前,我们先介绍几个概念。 一.文法涉及的几个简单概念 假设Σ是一个有限的 字母表集合 ,它的每一元素都是一个 符号 。Σ上的一个 符号串 就是指由Σ中的符号组成的一个有限序列。如果一个符号串不包含任何符号,就叫它 空串 ,记为ε。现在再定义一个集合U和V的 连接积 的概念:          UV = {αβ | α∈U,β∈V} 比如A = {a,b},B = {1,2},则AB={a1,a2,b1,b2}

C++ 多重继承(环状继承)

不羁岁月 提交于 2019-12-15 07:10:09
虚基类解决二义性模糊性问题 ambigous 二义性、模糊性 继承定义虚基类 (子类继承父类的时候,在父类前加 virtual) # include <iostream> using namespace std ; //基类 class Beauty { public : string name ; double height ; protected : int age ; private : double weight ; // public : Beauty ( ) { } Beauty ( string n , int a , double h , double w ) { name = n ; age = a ; height = h ; weight = w ; } void setinfo ( string n , int a , double h , double w ) { name = n ; age = a ; height = h ; weight = w ; } double get_weight ( ) { return weight ; } void show ( ) { cout << name << " " << age << " " << height << " " << weight << endl << endl ; } ~ Beauty (

Spring 自动装配的二义性

坚强是说给别人听的谎言 提交于 2019-12-04 07:14:42
1.我们知道可以用Spring的自动装配(@Autowired)将Bean应用注入到构造参数和属性中,但是,注意了,仅有一个bean匹配需要的结果时,自动装配才可以生效。如果有多个bean匹配同一个结果,这种歧义性会阻碍Spring自动装配属性,构造参数或方法参数。 大白话说一下,就如我们有一个甜片接口(Dessert)里面有一个好吃的方法(good)当我们只有一个饼干实现这个接口时,Spring容器会选择饼干来装配,但是还有一个蛋糕实现接口时,这个时候Spring就不知道去选择哪个实现类来装配了。代码上! (1)甜片的接口 package jinjin; /** * * @author 雪飞oubai * 甜点接口 */ public interface Dessert { public void good(); } (2)有饼干实现这个接口 package jinjin; import org.springframework.stereotype.Component; /** * @author 雪飞oubai * 饼干类实现接口 */ @Component public class Cookies implements Dessert{ @Override public void good() { System.out.println("饼干好吃!"); } } (3)测试类

编译原理 四

瘦欲@ 提交于 2019-11-30 12:33:53
1. 梳理第二章的内容,写一篇理解与总结。 当我们要描述一种语言时,需要给出这种语言的所有句子,当句子的数目是有限可数时,就要都列出来;当句子 是一个无穷集,也就是无限不可数时,就要给出可以表示它们的结构的描述方法或者说,句子的组成规则。这种 规则就是文法。 从形式上用于描述和规定结构的称为文法(或者说语法) 一、文法的定义: 文法G定义为一个四元组(VN,VT,P,S),其中, VN为非终结符集合,VT终结符集合;P是产生式结合;S称为识别符或开始符号,也是一个非终结符,至少要在一 条产生式的左边出现。 出现了几个名词,终结符、非终结符、产生式、识别符/开始符号等。下面具体聊聊这些名词和文法的定义。 VN是非终结符集合,非终结符N指的是可以被拆分的字符或串,它采取递归定义:一个非终结符是由终结符和至少 一个非终结符组成的串,相对应的,终结符就是不可拆分的,语言中要用到的字符。所以VN中所存储的是所有的 非终结符,VT中存储的是所有的终结符。 简单点讲:终结符就是推导到终结符时,不可再推导下去;而非终结符可以继续推导下去。 集合P存储的是所有的产生式。那什么是产生式呢?产生式就是推导规则。比方说 a→b 就是一条规则,即一条产 生式,可以通过 a 推导出 b。 对照前面说的非终结符和终结符,就应该可以理解,在产生式左边的只能是非终结符,因为终结符不能再推导下 去

#编译原理# 文法和内容(二)

偶尔善良 提交于 2019-11-29 17:35:18
文法和内容 编译原理笔记第二部分,内容参考:北航软院教师邵兵课堂课件及内容、张莉著《编译原理及编译程序构造》、国防工业出版社的《编译原理——学习指导与典型题解析》、 AlvinZH的学习笔记 以及个人理解 目前是包含了全部内容的版本,后续会推出精简版和复习知识点版 如有建议或错误错误欢迎在评论中指出或联系我:QQ:847590417 阅读目录 本章内容 2.1 形式语言基础 2.2 文法的非形式讨论 2.3 文法和语言的形式定义 2.4 语法树和二义性文法 2.5 句子的分析 2.6 有关文法的实用限制 2.7 文法的其他表示法 2.8 文法和语言分类 习题内知识 本章内容 重点:符号串、符号串集合的计算、文法、语言、递归、短语、句柄、语法树、文法的二义性、文法的使用限制、BNF表示文法、语法图、文法的分类。 2.1 形式语言基础 一、字母表和符号串 字母表:符号的非空有限集 符号:字母表中的元素 符号串:由符号拼接成的有穷序列 空符号串:没有任何符号的符号串 符号串的形式定义: 假设有一个字母表P:1.空符号串是P上的符号串;2.若x是P上的符号串,且a是字母表里的一个元素,则ax或xa(可以左,可以右,但只能一个不能同时加)是P上的符号串(一个符号也是符号串,a拼接ε);3.y是P上的符号串,当且仅当(iff)y是符合1.和2.的符号串。 二、符号串和符号串集合的运算 1

js中那些具有二义性的符号

半腔热情 提交于 2019-11-29 08:39:20
, 连续运算符; 参数分隔符; 对象/数组声明分隔符; 增值运算符; 正值运算符; 连接运算符 () 函数调用运算符; 强制运算,优先级; 形式参数表; ?: (问号没有二义性) 条件运算符; 冒号声明标签含义; 冒号声明switch分支含义; 冒号声明对象成员的含义; [] 数组下标;(运算符) 对象成员存取;(运算符) 数组直接量声明; {} 函数直接量代码部分声明; 对象直接量声明; 复合语句; ; 空语句; 语句分隔符; 转载于:https://my.oschina.net/u/1792175/blog/598040 来源: https://blog.csdn.net/chuomu8273/article/details/100682027