Reg*_*ego 5 c++ java algorithm ada
也许C++和Java人员可以帮助我定义我将要解释的这个问题.关于如何表示实现动态标识符的三个主要分支的类的构造函数,我在Ada(你不需要知道它,我只是对这个概念感兴趣)有一个问题:
我要调用这个类Par_Class,并且是任何构造的对象调用Par_Obj.因此,当Par_Obj创建一个对象时(因此,数值被初始化,列表/堆栈分配了其他列表/堆栈或为空并且保留了线程执行的内存范围),OS自动开始执行新线程与我的主应用程序并行(现在他们争夺系统资源).但是为了简化示例,让我们假设我有一个带有整数的类和一个指向字符串的指针.
例如,在C++中,我可以编写代码(如果我做错了,请纠正我)
class Par_Class {
public:
Par_Class (int aValue, const std::string & aName);
private:
int theValue;
std::string theName;
};
Run Code Online (Sandbox Code Playgroud)
构造函数可以实现为
Par_Class::Par_Class (int aValue, const std::string & aName)
: theValue(aValue)
, theName(aName)
{
}
Run Code Online (Sandbox Code Playgroud)
最后我们可以实例化这个类
Par_Class Par_Obj (23, "My object is this");
Run Code Online (Sandbox Code Playgroud)
并确保此构造方法属于Par_Class类,而不属于任何其他类.
同样,在Java中,我们可以编码
public class Par_Class {
private int theValue;
private String theName;
public Par_Class (int aValue, String aName){
theValue = aValue;
theName = aName;
}
};
Run Code Online (Sandbox Code Playgroud)
我们可以使用实例化对象
Par_Class Par_Obj = new Par_Class (23, "My object is this");
Run Code Online (Sandbox Code Playgroud)
(如果我错了,请再次纠正我).同样,Par_Class构造函数是类的方法Par_Class.
在Ada 2005中,这个类可以编码为
--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;
Run Code Online (Sandbox Code Playgroud)
并且用户可以打电话
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;
Run Code Online (Sandbox Code Playgroud)
这就是问题所在.编译器告诉我,我无法使用Construct方法,Par_Obj := Par_Obj.Construct因为我的对象是null.但它是如此明显,因为我想要做的就是初始化对象(所以它不再是null).还有其他构造对象的方法,例如,使用类外部的函数,但我不想使用这种方法,因为它远离架构.你能帮我把问题告诉我的Ada朋友,这样他们可以帮我在Ada中实现吗?我想我在一般概念术语中解释这个问题有点困难.谢谢.
回答
@paercebal给了我我认为可以实现我的目标:
我可以用"有没有办法在标记类型中声明一个"静态"函数来完成它?另外,声明类的包可以充当朋友还是静态函数?"
更新
根据@SimonWright和comp.lang.ada论坛的一些人的建议,为什么实现它有一些更好的理由:
function Construct (aValue: Integer; aName: Integer)
return Par_Class is
begin
return (theValue => aValue,
theName => aName);
end Construct;
Run Code Online (Sandbox Code Playgroud)
所以我问:在这种情况下,函数Construct会表现为C++静态函数(或者可能是朋友吗?)?
德米特里卡扎科夫回答说:
这取决于你的意思.在阿达:
没有隐藏的参数
操作可以在参数和/或结果的任何组合中调度(虚拟).但是操作不能在多种类型中调度(没有多次调度).调度参数的所有标签必须相同(没有多方法).
由于可见性规则基于包,因此没有静态或朋友操作.
上面的函数Construct是一个原始操作,它不是构造函数.
Ada中的构造函数是隐含的,它们由
组件的构造(以未指定的顺序,递归地);
如果类型是Ada.Finalization的后代,则调用Initialize.[Limited_]受控制.(不会调用重写的Initialize主体!即Ada构造函数不会遍历派生路径.简而言之,聚合是安全的,派生不是;
启动所有任务组件.(注意,调用Initialize时任务没有运行!)
析构函数按相反顺序执行:tasks - Finalize - components.
我猜它会回应.谢谢大家
很难解释这个概念,因为我不了解 Ada 语言的哲学、局限性和优势。不过,猜测 Ada 中没有构造函数。
我猜这不是你想要的解决方案:
Initialize成员函数Par_Class,它设置 的私有数据Par_ClassPar_Class_Constructor非成员函数调用该初始化函数但这个解决方案并不令人满意,因为它会公开Initialize为公共方法,这违反了封装性(任何人都可以随时调用该方法,这几乎与公开所有数据一样愚蠢)。
您想要做的是仅使用一个函数调用来分配和初始化您的代码,而不破坏封装。
你觉得(正确地)这个函数应该是Par_Classinterface的一部分,因此,你想在Par_Class' 声明中声明它(这将产生一个有趣的副作用,即让它访问Par_Class私有成员变量)
在 Java 或 C++ 中,除了构造函数之外,可以通过使用静态方法(即类的方法,而不是实例的方法)来解决此问题。此方法是static,因此无法访问this意味着您可以在不需要 的实例的情况下调用它Par_Class。
所以,你对 Ada 朋友的问题可能是:有没有办法在内部声明一个“静态”函数Par_Class?
另一种具有类似效果的方法(如果不是类似的语法糖)是使用非成员函数来实现这一目的。在 C 中,您将拥有类似: 的函数,该函数返回指向Par_Class 类型的Par_Class_Constructor指针。struct
在 C++ 中,您可以使用与 Java 相同的技巧,或者与 C 相同的技巧。在最后一种情况下,Par_Class_Constructor将声明类friend以Par_Class访问其私有数据,或者可以调用有权访问该私有数据的初始化成员方法私人数据。
这样,您仍然可以用一个函数分配和初始化您的对象,并且仍然保护您的类的封装(因为此方法返回一个新对象,而不是像Initialize上面描述的不令人满意的方法那样修改它)
因此,如果拥有一个非成员函数对您来说没问题,另一种可能性可能是:有没有办法声明一个非成员函数?friendPar_Class
注意:我之前的题外话答案……我真的应该去睡觉了……
我不认识 Ada,但阅读你的代码:
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;
Run Code Online (Sandbox Code Playgroud)
我看到 Int_Obj 已经用new Integer语句分配了。
您不需要以同样的方式分配 Par_Obj 吗?
像这样的东西(我从你的整数初始化代码推断):
Par_Obj := new Par_Class_Ptr -- allocate ?
Par_Obj.all := Par_Obj.Construct -- initialize ?
(aValue => 23,
aName => Int_Obj);
Run Code Online (Sandbox Code Playgroud)
???