Может быть, C ++ и Java люди могут помочь мне определить эту проблему, которую я собираюсь объяснить.У меня есть проблема в Аде (вам не нужно это знать, мне просто интересна концепция) о том, как представить конструктор класса, который реализует три основные ветви динамических идентификаторов:
- Чистые числовые значения (int, float, String, что угодно)
- Элемент списка / стека
- Что-то, что в C ++, вероятно, thread (в Ada у нас есть болееШирокая концепция этого, относящаяся к задача , но мы можем представить простую задачу как поток, так что концепция также применима)
Я назову этот класс Par_Class
, и любой построенный объект вызывает Par_Obj
.Таким образом, когда создается объект Par_Obj
(то есть, числовые значения инициализируются, списки / стеки имеют другие списки / стеки, выделенные или равные нулю, и диапазон памяти для выполнения потока зарезервирован), ОС автоматически запускает выполнениеновый поток параллельно с моим основным приложением (и теперь они борются за системные ресурсы).Но чтобы упростить пример, давайте предположим, что у меня есть класс с целым числом и указателем на строку.
В C ++ я мог бы, например, написать код (пожалуйста, исправьте меня, если я делаю неправильно)
class Par_Class {
public:
Par_Class (int aValue, const std::string & aName);
private:
int theValue;
std::string theName;
};
конструктор может быть реализован как
Par_Class::Par_Class (int aValue, const std::string & aName)
: theValue(aValue)
, theName(aName)
{
}
, и, наконец, мы можем создать экземпляр этого класса с помощью
Par_Class Par_Obj (23, "My object is this");
и убедиться, что этот метод конструктора принадлежиткласс Par_Class, а не какой-либо другой класс.
Аналогично, в 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
.
. В 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;
, и пользователь может вызвать
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;
И вот в чем проблема.Компилятор говорит мне, что я не мог использовать метод Construct в Par_Obj := Par_Obj.Construct
, потому что все же мой объект нулевой.Но это так очевидно, потому что я просто хочу инициализировать объект (чтобы он больше не был нулевым).Существуют и другие способы конструирования объекта, например, использование функции извне класса, но я не хочу использовать этот подход, потому что он уходит от архитектуры.Не могли бы вы помочь мне сформулировать проблему моим друзьям по Аде, чтобы они помогли мне реализовать ее в Аде?Я думаю, мне сложно объяснить это в общих чертах.Спасибо.
Ответ
@ paercebal дал мне то, что, как я думаю, могло бы достичь моей цели:
- "Есть ли способ получить"статическая" функция объявлена внутри Par_Class? "и "есть ли способ сделать функцию, не являющуюся членом, объявленной другом Par_Class?"
Я мог бы дополнить это "есть ли способ объявить" статическую "функцию внутри тегового типа? Кроме того, может ли пакет, в котором объявлен класс, действовать как друг или как статическийfunction? "
Обновление
У вас есть еще несколько веских причин для его реализации в соответствии с предложением @SimonWright и некоторых людей с форума comp.lang.ada:
function Construct (aValue: Integer; aName: Integer)
return Par_Class is
begin
return (theValue => aValue,
theName => aName);
end Construct;
Итак, я спросил: в этом случае функция Construct будет вести себя как статическая функция C ++ (или, может быть, друга?)?
А Дмитрий Казаков ответил:
Это зависит от того, что вы имеете в виду.В Ada:
нет скрытых параметров
операция может быть диспетчеризована (виртуально) в любой комбинации параметров и / или результата.Но операция не может быть отправлена более чем в один тип (без многократной отправки).Все теги параметров диспетчеризации должны быть одинаковыми (без мульти-методов).
нет статических или дружественных операций, поскольку правила видимости основаны на пакетах.
Функция Construct выше является примитивной операцией, а не конструктором.
Конструкторы в Аде неявные, они состоят из
построение компонентов (в неуказанном порядке, рекурсивно);
вызов Initialize, если тип является потомком Ada.Finalization. [Limited_] Управляется. (Переопределены тела
Инициализация не называется! То есть Ада конструкторы не пересекают
путь деривации. Короче говоря, агрегация безопасна, деривация - нет;
запуск всех компонентов задачи. (Обратите внимание, что при вызове Initialize задачи не выполняются!)
Деструкторы действуют в обратном порядке: задачи - Завершение - компоненты.
И я думаю, это отвечает. Спасибо, люди.