Object Oriented Programming Concepts
类是可以组合在一起的一组属性和相关行为。对象是类的实例,表示具有属性和行为的真实实体。可以使用类数据成员来表示属性,而可以使用方法来表示行为。例如:可以将动物表示为一类,而不同的动物(如狗,猫等)可以是该动物的对象。
最初,在C中定义了一个“结构体”,以将不同的数据类型组合在一起以执行某些已定义的功能。但是,在C++中,这种结构体也扩展为包括函数的结构。“类”也是一种数据类型,可以将不同的数据类型和其对应的方法进行分类。C++中两者的区别之一是,类的所有成员默认情况下都是私有的,而结构的所有成员默认情况下都是公共的。
在SystemVerilog中,基于要执行的某些功能,类和结构都用于定义一堆数据类型。但是,结构是整体式的类型,在声明结构时会分配必要的内存。类是动态类型,一旦声明了一个类,就只能将一个类句柄引用为null。内存分配仅在创建该类的实际对象时发生。
这三者是类成员的不同访问属性
多态性是指具有多种形式的能力。在OOP上下文中,这是指实体在运行时引用各种类的对象的能力。这可以通过SystemVerilog中的继承和虚函数的概念(以及C++中存在的函数和运算符重载的概念)来实现。根据对象的类型,将从相应的类中调用适当的方法。
在面向对象的编程中,运算符重载是多态的一种特殊情况,可以重新定义或重载可用的不同内置运算符。因此,程序员也可以将运算符与用户定义的类型一起使用。C++支持此功能,而SystemVerilog不支持此功能。以下示例显示了一个Testclass,其中运算符+被重载,从而可以把两个类型为“Testclass”的类对象相加。然后,实现将来自两个对象的数据成员相加,并将其分配给结果类的数据成员。
#include <iostream>
class Testclass{
public:
int a;
int b;
Testclass operator+(const Testclass& obj);
}
Testclass Testclass::operator+(const Testclass& obj2){
Testclass tmp_obj = *this;
tmp_obj.a = tmp_obj.a + obj2.a;
tmp_obj.b = tmp_obj.b + obj2.b;
return tmp_obj;
}
int main(void){
Testclass obj1, obj2, obj3;
obj1.a = 1;
obj1.b = 1;
obj2.a = 2;
obj2.b = 2;
obj3.a = 0;
obj3.b = 0;
obj3 = obj1 + obj2;
std::cout<<obj3.a<<" "<<obj3.b<<"\n";
return 0;
}
构造函数是类的特殊成员函数,每当创建该类的实例时,构造函数就会自动调用。在C++中,它与类具有相同的名称。在SystemVerilog中,它作为new()函数实现。
与构造函数相反,当对象结束其生命周期,如对象所在的函数已调用完毕时,系统会自动执行析构函数。在C++中,它与类具有相同的名称,并带有波浪号字符前缀,而在SystemVerilog中,由于该语言支持自动垃圾收集,因此没有析构函数。
组合使两个类之间具有“has - a”关系。当一个类实例化另一个类的对象时,该关系为“ has-a”,并且此属性称为composition。
继承使两个类之间具有“is - a”关系。当一个类从另一个类派生时,该关系为“ is-a”,并且此属性称为继承。
下图说明了这一点。基类汽车中派生出福特类,则该关系为“is-a”,这意味着福特类为汽车类。如果福特类内部具有引擎类的对象,则关系为“has - a”,如图所示。
在浅拷贝中,将创建一个新对象,该对象具有与原始对象中的值完全相同的副本。如果对象的任何字段是对其他对象的引用,则仅复制引用地址(句柄)。在深拷贝中,将创建一个新对象,该对象具有与原始对象相同的值的精确副本。如果任何对象都引用了其他对象,则还将复制属于该对象的所有值的副本,而不仅仅是内存地址或句柄。因此,称为深拷贝。
例如,对比如下两个类。
class A;
int a;
int b;
endclass
class B;
int c;
A objA;
endclass
如果在类B中实现了浅拷贝方法,则当我们将B复制到新对象时,仅复制“ objA”的内存句柄。在深度复制的情况下,还将复制A的所有值(即其数据成员a和b),而不是“objA”的内存句柄。
虚方法是在基类中声明的成员方法,并且可以由派生类重新定义。要创建虚方法,在基类中的方法声明之前要加上关键字virtual。在派生类中重新定义基类方法的这种方式也称为方法重写。使得调用方法时,是根据对象类型而不是句柄类型调用函数。
多重继承是某些面向对象的计算机编程语言的功能,其中对象或类可以从多个父对象或父类继承特征和功能。它不同于单一继承,在单一继承中,一个对象或类只能从一个特定的对象或类继承。注意:C++支持多重继承,而SystemVerilog语言则不支持。
抽象类是包含一个或多个抽象方法的类。抽象方法是已声明但不包含任何实现的方法。抽象类可能无法实例化,并且需要子类为抽象方法提供实现。在SystemVerilog中,类名前面带有虚拟关键字,以使其成为抽象类。以下是如何使用函数定义为virtual定义抽象类的示例。然后派生的类可以实现此功能。相当于一个模板类。
静态方法是使用static关键字在类内部定义的方法。可以在不创建类对象的情况下使用它们。同样,如果有多个此类创建的对象,则仍然只有一个静态方法成为所有对象的一部分。
该指针是一个特殊的指针,可用于在类范围内引用该类的当前对象。
type conversion 和 type casting的最大区别就是,type conversion有编译器自动(隐式)转换的,而type casting是显式完成的。
比较内容 | type casting | type conversion |
---|---|---|
意义 | 一个数据类型由用户分配给另一个数据类型,使用强制转换运算符,称为"type casting"。 | 编译器自动将一种数据类型转换为另一种数据类型称为"type conversion"。 |
应用 | 类型强制转换也可以应用于两个"不兼容"的数据类型。 | 仅当两个数据类型"兼容"时,才能实现类型转换。 |
算子 | 要将数据类型强制转换到另一个数据类型,需要强制转换运算符"()"。 | 无需操作符。 |
实现 | 它在程序设计过程中完成。 | 它在编译时显式完成。 |
下面第一个例子是type casting,第二个是type conversion
int a;
byte b;
...
...
b= (byte) a;
////////////////////////////////////////
int a=3;
float b;
b=a; // value in b=3.000.
通过man <command-name> ,例如man grep
任意一种:
a) head -10 file.txt
b) cat file.txt | head -10
c) sed “11,$ d” file.txt
head -10 file.txt | tail -1
sed -i “13 d” file.txt
sed -i “$ d” file.txt
echo “Hello” | rev
echo $?
cat file.txt | wc -l
cat file.txt | wc -c
head -17 file.txt | tail -1 | wc -c
head -17 file.txt | tail -1 | cut -f3 -d’ ‘
chmod 555 file.txt
chgrp new_group file.txt
cat file1.txt file2.txt > file.txt
ps -aef
sort -u file1.txt > file2.txt
whoami
ssh username@remote-server
grep “cat” file.txt
grep -w “cat” file.txt
grep -v -w “cat” file.txt
grep -i “cat” file.txt
grep “^cat” file.txt
grep “cat$” file.txt
grep “cat.*123” file.txt