friend
ключевое слово имеет много хорошего использования. Вот два использования, сразу видимое мне:
определение позволяет определять функцию в объеме класса, но функция не будет определена как функция членства, но как бесплатная функция пространства имен включения, и обычно не будет видима за исключением зависимого поиска аргумента. Это делает его особенно полезным для перегрузки оператора:
namespace utils {
class f {
private:
typedef int int_type;
int_type value;
public:
// let's assume it doesn't only need .value, but some
// internal stuff.
friend f operator+(f const& a, f const& b) {
// name resolution finds names in class-scope.
// int_type is visible here.
return f(a.value + b.value);
}
int getValue() const { return value; }
};
}
int main() {
utils::f a, b;
std::cout << (a + b).getValue(); // valid
}
CRTP Иногда, Вы находите потребность, что политике нужен доступ к производному классу:
// possible policy used for flexible-class.
template
struct Policy {
void doSomething() {
// casting this to Derived* requires us to see that we are a
// base-class of Derived.
some_type const& t = static_cast(this)->getSomething();
}
};
// note, derived privately
template class SomePolicy>
struct FlexibleClass : private SomePolicy {
// we derive privately, so the base-class wouldn't notice that,
// (even though it's the base itself!), so we need a friend declaration
// to make the base a friend of us.
friend class SomePolicy;
void doStuff() {
// calls doSomething of the policy
this->doSomething();
}
// will return useful information
some_type getSomething();
};
Вы найдете неизобретенный пример для этого в этот ответ. Другой код с помощью то, который находится в этот ответ. Основа CRTP бросает свой этот указатель, чтобы быть в состоянии получить доступ к полям данных производного класса с помощью указателей элемента данных.
Чтобы показать, насколько просто позволить двум приложениям взаимодействовать друг с другом, посмотрите эту демонстрацию сетевого буфера обмена с помощью JGroups. Просто запустите два экземпляра и начните перетаскивать файлы в один из них. Во втором экземпляре мгновенно отобразятся те же файлы.
import java.io.Serializable;
import java.awt.*;
import java.awt.datatransfer.*;
import javax.swing.*;
import org.jgroups.*;
public class JGroupsTest {
public static void main(String[] args) throws Exception {
final JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(500, 300);
final DefaultListModel listModel = new DefaultListModel();
final JList panel = new JList(listModel);
panel.setBackground(new Color(128, 0, 40));
panel.setForeground(new Color(240, 240, 240));
frame.add(panel);
System.setProperty("java.net.preferIPv4Stack", "true");
final JChannel channel = new JChannel("udp.xml");
channel.connect("networkclipboard");
channel.setReceiver(new ReceiverAdapter() {
@Override
public void viewAccepted(View newView) {
frame.setTitle("Network Clipboard - " + channel.getLocalAddress());
}
@Override
public void receive(Message msg) {
listModel.addElement(msg.getObject());
}
});
panel.setTransferHandler(new TransferHandler() {
@Override
public boolean importData(JComponent comp, Transferable t) {
DataFlavor[] transferDataFlavors = t.getTransferDataFlavors();
for (DataFlavor flavor : transferDataFlavors) {
try {
Object data = t.getTransferData(flavor);
if (data instanceof Serializable) {
Serializable serializable = (Serializable) data;
Message msg = new Message();
msg.setObject(serializable);
channel.send(msg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return super.importData(comp, t);
}
@Override
public boolean canImport(TransferSupport support) {
return true;
}
@Override
public boolean canImport(JComponent comp, DataFlavor[] transferFlavors) {
return true;
}
});
}
}
Каждый из них мог прослушивать сокет
. Это руководство удобно для начала.
Попробуйте установить связь с SocketCommunication, даже если приложение находится на том же компьютере.
Здесь можно найти дополнительную информацию о , как это сделать (документация Sun / Java ).
Взгляните на JavaGroups , это решит вашу проблему со связью, а также поможет вам определить, работает ли другое приложение. Если приложение не запущено, вам придется запустить для него новую JVM с помощью java.lang.Runtime.exec () ...
Вам также следует подумать о старой доброй классической RMI.
"Корпоративный" способ - запускать эти приложения на сервере Java EE или, по крайней мере, в среде Spring. Это также, вероятно, чрезмерно.
Если необходимо передать кучу данных, RMI сделает это.
Если вы не боитесь взломать свой собственный протокол, структуру данных и обработку ошибок, вы можете настроить серверные и клиентские сокеты и общаться
Я думаю, что есть некоторая грубая апелляция к альтернативе связи через файл в общем каталоге (настройка вашего собственного протокола, который определяет, кто записывает или стирает файл и когда) или через общую базу данных. Низкотехнологичный, не очень быстрый, но очень простой и надежный. И довольно легко отслеживать "общение" извне.
Это зависит от того, какой вид связи вы хотите установить между двумя приложениями. Если вы, например, используете сокеты или RMI, оба приложения должны быть активными, чтобы связь могла происходить. Если тип связи, который вы хотите осуществлять, может быть более асинхронным, вы можете использовать больше подход, основанный на обмене сообщениями.
Например, ZooKeeper позволяет реализовать практически все, что угодно, поверх очень простых, но мощных примитивов. На этой странице ( http://hadoop.apache.org/zookeeper/docs/current/recipes.html ) объясняется, как создавать конструкции более высокого уровня с помощью ZooKeeper.
Недостатком является то, что вам нужна другая система . Если вы, например, используете JGroups, то вы этого не сделаете.
Надеюсь, это поможет
В зависимости от того, какой стиль общения вы ищете (высокая задержка, много данных и т. Д.), И от того, может ли эта система расширяться за пределы двух систем Java, вероятность может быть система обмена сообщениями, использующая промежуточное программное обеспечение, такое как Tibco SmartSockets.
Дополнительная информация о ваших настройках и ожиданиях может помочь.
Второе соединение с сокетами и RMI. RMI немного сложнее, но для программиста более интуитивно понятен. Это зависит от того, какую информацию вы отправляете. Передача необработанных байтов на другую машину может иметь больше смысла, чем запуск сервера RMI и работа со всем этим джазом ...
Для простоты почему бы просто не использовать простые сокеты TCP?