我试图理解Fortran 2003标准(或更高版本)中面向对象的概念.我对C++有一些了解,所以我认为这两种语言之间有一些共同点,可以帮助我更好地理解它们.
在C++中,多态性是通过类派生和成员函数覆盖来完成的.一个定义了一个"抽象"基类,几乎所有的虚函数都被定义了.不同的派生类包含它们的实际实现.所以其他函数只需要基于"抽象"类进行编程.然后它们适用于所有派生类.
我认为在Fortran中,OOP以类似的方式完成,但存在一些差异.在我看来,需要定义一个带有一些虚函数的基类型,就像C++一样.其他函数/子例程应遵循基类型中的成员函数定义.这是解决所有扩展类型的函数/子例程重用的方法.
我对如何编写这个想法没有更好的想法.这是我的第一次尝试:
type Basis
integer :: NBasis
contains
private
procedure :: DoNothing
generic, public :: Constructor => DoNothing
generic, public :: AllocateBasis => DoNothing
endtype Basis
type, extends(Basis) :: GridBasis
private
integer :: NGrid
contains
private
procedure :: ConstructorGrid1
procedure :: ConstructorGrid2
generic, public :: Constructor => ConstructorGrid1, ConstructorGrid2, ConstructorGrid3
procedure :: AllocateGridReal
procedure :: AllocateGridCplx
generic, public :: AllocateBasis => AllocateGridReal, AllocateGridCplx
endtype GridBasis
Run Code Online (Sandbox Code Playgroud)
首先,我如何在类型Basis中定义"AllocateBasis",使其像"虚函数"一样工作,所有扩展类型必须定义自己的"AllocateBasis"版本?
其次,如何在GridBasis类型中定义"AllocateBasis"?这里的定义包含它的真实实现.
第三,如何在GridBasis类型中使"AllocateBasis"成为重载函数?即存在真实版本和复杂版本,并且它们都被命名为"AllocateBasis",具有实际或复杂的输入可分配数组.
第四,NOPASS与PASS.据我所知,如果设置了PASS,那么就会有一个指向该对象的显式指针.但是当NOPASS设定时,就没有这样的东西了.那么PASS是简化澄清的吗?
我可能会问一个愚蠢的问题,但我真的找不到谷歌的答案加上我仍然是使用MSVS的初学者.
我最近需要使用函数来比较两个字符串.我不明白的是stricmp和_stricmp的区别.它们都可用于比较字符串并返回相同的结果.我去检查一下:
char string1[] = "The quick brown dog jumps over the lazy fox";
char string2[] = "The QUICK brown dog jumps over the lazy fox";
void main( void )
{
char tmp[20];
int result;
/* Case sensitive */
printf( "Compare strings:\n\t%s\n\t%s\n\n", string1, string2 );
result = stricmp( string1, string2 );
if( result > 0 )
strcpy( tmp, "greater than" );
else if( result < 0 )
strcpy( tmp, "less than" );
else
strcpy( tmp, "equal to" );
printf( "\tstricmp: …Run Code Online (Sandbox Code Playgroud) 我将在Windows中使用NetCDF,我认为它必须用MinGW编译,因为我的主程序和所有其他库已经用MinGW编译.
但是当我使用MinGW(gcc版本4.6.2)时.我收到一些错误消息:
Making all in liblib
make[2]: Entering directory `/c/Users/ylylyl/Documents/CB/NETCDF/netcdf-4.2.1.1/liblib'
/bin/sh ../libtool --tag=CC --mode=compile gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DDLL_NETCDF -DDLL_EXPORT -g -O2 -MT libnetcdf_la-stub.lo -MD -MP -MF .deps/libnetcdf_la-stub.Tpo -c -o libnetcdf_la-stub.lo `test -f 'stub.c' ||echo './'`stub.c
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DDLL_NETCDF -DDLL_EXPORT -g -O2 -MT libnetcdf_la-stub.lo -MD -MP -MF .deps/libnetcdf_la-stub.Tpo -c stub.c -DDLL_EXPORT -DPIC -o .libs/libnetcdf_la-stub.o
libtool: compile: gcc -DHAVE_CONFIG_H -I. -I.. -I../include -DDLL_NETCDF -DDLL_EXPORT -g -O2 -MT libnetcdf_la-stub.lo -MD -MP -MF .deps/libnetcdf_la-stub.Tpo -c stub.c -o …Run Code Online (Sandbox Code Playgroud) 与C不同,Fortran在每种情况下都不需要休息.但有没有办法跳出选择案例陈述goto?(如果可能的话,我宁愿选择其他方式跳转,我也不能在select case语句中使用exit.)
select case(key)
case("cat")
if(value > 5) !break!
case("dog")
...
endselect
Run Code Online (Sandbox Code Playgroud)
这是一个更详细的例子.虽然还有其他类型的流量控制,但在我看来,休息将是最好的
integer, allocatable :: Err(:)
select case(key)
case("cat")
if(value1 > 5) call PushBack(Err, 1001)
if(NotANumber(value2)) call PushBack(Err, 1002)
if(value3 /= "good") call PushBack(Err, 1003)
if(allocated(Err)) !break!
.... !some processing
case("dog")
....
endselect
if(allocated(Err)) call ShowError(key, Err)
Run Code Online (Sandbox Code Playgroud)
如果我把所有东西放进去:
integer, allocatable :: Err(:)
select case(key)
case("cat")
if(value1 > 5) then !Here only one of the value1, value2... is checked
call PushBack(Err, 1001)
elseif(NotANumber(value2)) then
call PushBack(Err, 1002)
elseif(value3 …Run Code Online (Sandbox Code Playgroud) 我试图隐藏真实和复杂数据类型之间的差异.在FORTRAN 2003中,我认为可以有这样做的方法.
目标是定义一个多态可分配数组,该类型可以在运行时决定.另外还有一个子程序,它使多态数组做一些代数(相同的方程适用于实数和复数数据).
为了做到这一点,我做了两次尝试:
方法A:
module poly
implicit none
private
type, abstract, public :: MyType
contains
procedure, public :: Constructor
endtype MyType
type, extends(MyType), public :: MyTypeR
real(8), allocatable :: AllData(:)
endtype MyTypeR
type, extends(MyType), public :: MyTypeI
complex(8), allocatable :: AllData(:)
endtype MyTypeI
contains
subroutine Constructor(this, Nsize)
class(MyType), intent(inout) :: this
integer, intent(in) :: Nsize
select type(this)
type is(MyTypeR)
allocate(this%AllData(Nsize))
type is(MyTypeI)
allocate(this%AllData(Nsize))
endselect
endsubroutine
endmodule poly
! Algebra subroutine
module Operation
contains
subroutine Square(Array)
class(*), intent(inout) :: Array(:) …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用另一种类型的类型。但是,我不能让它编译。我很奇怪:选择类型的东西在主程序中工作,但它在类型的子例程中不起作用。
module ModBuffer
implicit none
private
type, abstract, public :: Buffer
contains
procedure, public :: Constructor
endtype Buffer
type, extends(Buffer), public :: BufferR
real(8), allocatable, public :: BufData(:,:,:)
endtype BufferR
type, extends(Buffer), public :: BufferI
complex(8), allocatable, public :: BufData(:,:,:)
endtype BufferI
contains
subroutine Constructor(this, dim1, dim2, dim3)
class(Buffer), intent(inout) :: this
integer, intent(in) :: dim1, dim2, dim3
select type(this)
type is(BufferR)
allocate(this%BufData(dim1, dim2, dim3))
type is(BufferI)
allocate(this%BufData(dim1, dim2, dim3))
endselect
endsubroutine Constructor
endmodule ModBuffer
module ModSystem
use ModBuffer
implicit …Run Code Online (Sandbox Code Playgroud) fortran ×4
fortran2003 ×2
polymorphism ×2
break ×1
c++ ×1
case ×1
conflict ×1
inheritance ×1
libtool ×1
mingw ×1
netcdf ×1
overriding ×1
runtime ×1
select ×1