C+中的类公式概念+;从Java到Ada 也许C++和java人可以帮助我定义这个问题,我要解释一下。我在Ada中遇到了一个问题(你不需要知道,我只是对这个概念感兴趣),即如何表示一个类的构造函数,该类实现了动态标识符的三个主要分支: 纯数值(int、float、String等) 列表/堆栈项 C++中的某个东西可能是一个线程(在艾达中,我们有一个更广泛的概念,它涉及到一个任务,但是我们可以把一个简单的任务看作一个线程,所以这个概念也适用于”
我将这个类称为C+中的类公式概念+;从Java到Ada 也许C++和java人可以帮助我定义这个问题,我要解释一下。我在Ada中遇到了一个问题(你不需要知道,我只是对这个概念感兴趣),即如何表示一个类的构造函数,该类实现了动态标识符的三个主要分支: 纯数值(int、float、String等) 列表/堆栈项 C++中的某个东西可能是一个线程(在艾达中,我们有一个更广泛的概念,它涉及到一个任务,但是我们可以把一个简单的任务看作一个线程,所以这个概念也适用于”,java,c++,algorithm,ada,Java,C++,Algorithm,Ada,我将这个类称为Par_类,是任何构造的对象调用Par_Obj。因此,当一个对象Par_Obj被创建时(因此,数值被初始化,列表/堆栈被分配了其他列表/堆栈或为空,线程执行的内存范围被保留),操作系统会自动启动与我的主应用程序并行的新线程的执行但是为了简化这个例子,让我们假设我有一个带有整数和字符串指针的类 在C++中,我可以编码,例如(如果我做错了请纠正我)< /P> 构造函数可以实现为 Par_Class::Par_Class (int aValue, const std::string &a
Par_类
,是任何构造的对象调用Par_Obj
。因此,当一个对象Par_Obj
被创建时(因此,数值被初始化,列表/堆栈被分配了其他列表/堆栈或为空,线程执行的内存范围被保留),操作系统会自动启动与我的主应用程序并行的新线程的执行但是为了简化这个例子,让我们假设我有一个带有整数和字符串指针的类
在C++中,我可以编码,例如(如果我做错了请纠正我)< /P>
构造函数可以实现为
Par_Class::Par_Class (int aValue, const std::string & aName)
: theValue(aValue)
, theName(aName)
{
}
最后我们可以用
Par_Class Par_Obj (23, "My object is this");
并确保此构造函数方法属于类Par_类,而不属于任何其他类
类似地,在Java中,我们可以编写代码
public class Par_Class {
private int theValue;
private String theName;
public Par_Class (int aValue, String aName){
theValue = aValue;
theName = aName;
}
};
我们可以使用
Par_Class Par_Obj = new Par_Class (23, "My object is this");
(同样,如果我错了,请纠正我)。同样,Par_Class
构造函数是类的一种方法Par_Class
在ADA2005中,这个类可以编码为
--par_pkg.ads
package Par_Pkg is
type Par_Class is tagged private;
type Par_Class_Ptr is access all Par_Class;
type Integer_Ptr is access Integer;
function Construct
(P : access Par_Class; aValue : Integer; aName : Integer_Ptr)
return Par_Class_Ptr;
private
type Par_Class is tagged
record
theValue : Integer;
theName : Integer_Ptr;
end record;
end Par_Pkg;
-- par_pkg.adb
package body Par_Pkg is
function Construct
(P : access Par_Class; aValue : Integer; aName : Integer_Ptr)
return Par_Class_Ptr is
pragma Unreferenced (P);
P_Ptr : constant Par_Class_Ptr := new Par_Class;
begin
P_Ptr.theValue := aValue;
P_Ptr.theName := aName;
return P_Ptr;
end Construct;
end Par_Pkg;
用户可以调用
with Par_Pkg; use Par_Pkg;
procedure Par_Main is
Par_Obj : Par_Class_Ptr;
Int_Obj : Integer_Ptr;
begin
Int_Obj := new Integer;
Int_Obj.all := 12; -- don't worry about been string or integer
Par_Obj := Par_Obj.Construct
(aValue => 23,
aName => Int_Obj);
end Par_Main;
这就是问题所在。编译器告诉我,我不能在Par_Obj:=Par_Obj.Construct
中使用方法构造,因为我的对象是空的。但这很明显,因为我只想初始化对象(这样它就不再是空的)。还有其他方法来构造对象,例如,使用类外的函数,但我不想使用这种方法,因为它脱离了体系结构。你能帮我向我的Ada朋友解释一下这个问题,这样他们就可以帮助我在Ada中实现它吗?我想我在解释这个问题时有点困难一般来说,谢谢
回答
@paercebal给了我我认为可以实现我的目标的东西:
- “有没有办法在paru类中声明一个“静态”函数?”和“有没有办法将一个非成员函数声明为paru类的朋友?”
function Construct (aValue: Integer; aName: Integer)
return Par_Class is
begin
return (theValue => aValue,
theName => aName);
end Construct;
<> >我问:在这种情况下,函数构造会表现为C++静态函数(或者朋友一)?< /P>
德米特里·卡扎科夫回答说:
这取决于你的意思。在Ada中:
- 具有
的Par_Class
成员函数,该函数设置Initialize
Par_Class
- 具有调用初始化函数的非成员函数的
Par\u Class\u构造函数
Initialize
公开为一个公共方法,这违反了封装(任何人都可以随时调用该方法,这几乎与公开所有数据一样愚蠢)
静态成员函数?
您要做的是只使用一个函数调用来分配和初始化代码,而不破坏封装
您认为(正确地)此函数应该是Par_类
接口的一部分,因此,您希望在Par_类
声明中声明它(这将有一个有趣的副作用,即允许它访问Par_类
私有成员变量)
function Construct (aValue: Integer; aName: Integer)
return Par_Class is
begin
return (theValue => aValue,
theName => aName);
end Construct;
with Par_Pkg; use Par_Pkg;
procedure Par_Main is
Par_Obj : Par_Class_Ptr;
Int_Obj : Integer_Ptr;
begin
Int_Obj := new Integer;
Int_Obj.all := 12; -- don t worry about been string or integer
Par_Obj := Par_Obj.Construct
(aValue => 23,
aName => Int_Obj);
end Par_Main;
Par_Obj := new Par_Class_Ptr -- allocate ?
Par_Obj.all := Par_Obj.Construct -- initialize ?
(aValue => 23,
aName => Int_Obj);
function Construct
(P : access Par_Class; aValue : Integer; aName : Integer_Ptr)
return Par_Class_Ptr;
Par_Class *a_Par_Class(int aValue, const char *aName);
function Construct
(aValue : Integer; aName : Integer_Ptr)
return Par_Class is
begin
return Result : Par_Class do
Result.theValue := aValue;
Result.theName := aName;
end return;
end Construct;
function Construct
(aValue : Integer; aName : Integer_Ptr)
return Par_Class_Ptr is
P_Ptr : constant Par_Class_Ptr := new Par_Class;
begin
P_Ptr.theValue := aValue;
P_Ptr.theName := aName;
return P_Ptr;
end Construct;
With
Ada.Text_IO;
Procedure Test is
package Par_Pkg is
type Par_Class is tagged private;
type Par_Class_Ptr is access all Par_Class;
type Integer_Ptr is access Integer;
function Construct
(aValue : Integer; aName : Integer_Ptr)
return Par_Class_Ptr;
private
type Par_Class is tagged
record
theValue : Integer;
theName : Integer_Ptr;
end record;
end Par_Pkg;
----------------------------
package body Par_Pkg is
function Construct
(aValue : Integer; aName : Integer_Ptr)
return Par_Class_Ptr is
--P_Ptr : constant Par_Class_Ptr := new Par_Class;
begin
Return Result: Par_Class_Ptr:= New Par_Class'( others => <> ) do
Result.theValue := aValue;
Result.theName := aName;
End Return;
end Construct;
end Par_Pkg;
----------------------------
use Par_Pkg;
Int_Obj : Integer_Ptr:= new Integer'(12);
Par_Obj : Par_Class_Ptr:= Construct(aValue => 23, aName => Int_Obj);
Begin
Ada.Text_IO.Put_Line( "Everything went fine!" );
exception
when others =>
Ada.Text_IO.Put_Line("Something went horribly wrong!");
End Test;