Часовой пояс: UTC + 3 часа




Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 37 из 87<  1 ... 34  35  36  37  38  39  40 ... 87  >
  Пред. тема | След. тема 
В случае проблем с отображением форума, отключите блокировщик рекламы
Автор Сообщение
 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
kexman писал(а):
Вопросик есть - по поводу auto_ptr - когда его использовать? А когда обычные указатели+delete?
Никогда :D
Использовать стоит лишь тогда, когда ты проводишь обработку эксепшенов, чтобы при выходе из скопа, в случае stack unwinding вызвался деструктор контейнера и освободил память объекта. Не используй как поле класса.

kexman писал(а):
В общем я разочаровался, и подумал, что зря потратил деньги. Зато сейчас понял, что купил очень хорошую книгу )
Приблизительно как я со Страуструпом мучался :D

_________________
Ку ку



Партнер
 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Daemon. Вчера в шоке был, прочел у Мейерса правило "Рассмотрите альтернативы виртуальным функциям". Это сильно :)
Есть вопрос к тебе - по проектированию - он связан с QT - ты же юзал эту библиотеку? Я уже голову сломал, достаточно объемный вопрос.
У меня в программе есть два основных виджета графическое QGraphicsView и дерево - QTreeView. В обоих окнах отображаются одни и те же объекты - в QGraphicsView их графическое представление, в QTreeView их иерархия. Мне нужно контекстное меню, причем для разных типов графических объектов оно должно отличаться. Для обоих виджетов, чтобы обработать событие контекстного меню надо переопределить виртуальную функцию contextMenuEvent. Приведу ее реализацию для TreeView, для графического виджета она будет аналогична:
Код:
void MyTreeView::contextMenuEvent(QContextMenuEvent *event)
{
   /*Участок кода, в котором контейнер objects заполняется
   списком указателей на выделенные объекты.
   Для обработчика контекстного меню в QGraphicsView есть аналогичный кусок*/

   QItemSelectionModel *selectionModel = this->selectionModel();
   QModelIndexList indexes = selectionModel->selectedIndexes();
   QModelIndex index;

   QList<MObject*> objects;
   foreach(index, indexes)
       if (index.isValid())
         objects.push_back( static_cast<MObject *>( index.internalPointer() ) );

   /*Здесь должно вызываться контекстное меню в точке экрана event->globalPos()
   Приведу стандартный код вызова контекстного меню на QT*/

   QMenu menu(this);
   menu.addAction(cutAct);
   menu.addAction(copyAct);
   menu.addAction(pasteAct);
                ... // действия зависимые от типа выделенных объектов
   menu.exec(event->globalPos());}

В общем у меня есть этот обработчик в разных классах. Поскольку по логике программы объекты одни и те же, меню должно быть тоже одним и тем же. Недолго думая я сделал класс TMenuManager, который выводит контекстное меню и стал вызывать его из обработчиков обоих виджетов:
Код:
void MyTreeView::contextMenuEvent(QContextMenuEvent *event)
{
   /*Участок кода, в котором контейнер objects заполняется
   списком указателей на выделенные объекты.
   Для обработчика контекстного меню в QGraphicsView есть аналогичный кусок*/

   QItemSelectionModel *selectionModel = this->selectionModel();
   QModelIndexList indexes = selectionModel->selectedIndexes();
   QModelIndex index;

   QList<MObject*> objects;
   foreach(index, indexes)
       if (index.isValid())
         objects.push_back( static_cast<MObject *>( index.internalPointer() ) );

   /*Создание объекта класса TMenuManager, передача ему в качестве параметров
   event - для вывода меню в точке event->globalPos() и
   контейнера с выделенными объектами - чтобы заполнить это меню.*/

   TMenuManager menuManager(this, event, objects);
   menuManager.showMenu();
}

Реализация TMenuManager:
Код:
//tmenumanager.h
class TMenuManager : public QObject
{
   Q_OBJECT

public:
   TMenuManager(QWidget *parent, QContextMenuEvent *theEvent, QList<MObject*> theObjects);
   ~TMenuManager();

   void showMenu();

private slots:
   void cut();
   void copy();
   void delete_();
   void properies();

private:
   void createActions();

   QList<MObject*> objects;
   QContextMenuEvent *event;
   QAction *cutAct;
   QAction *copyAct;
   QAction *propAct;
   QAction *deleteAct;

};

Код:
//tmenumanager.cpp
TMenuManager::TMenuManager(QWidget *parent, QContextMenuEvent *theEvent, QList<MObject*> theObjects)
   : QObject(parent), event(theEvent)
{
   createActions();
   objects = theObjects;
}

TMenuManager::~TMenuManager()
{

}

void TMenuManager::showMenu()
{
   if (!objects.empty())
   {
      QMenu menu(dynamic_cast<QWidget*>(parent()));
      menu.addAction(cutAct);
      menu.addAction(copyAct);
      menu.addAction(deleteAct);
      menu.addSeparator();
      menu.addAction(propAct);
      menu.exec(event->globalPos());
   }
}

void TMenuManager::createActions()
{
   cutAct = new QAction(tr("Вырезать"), this);
    cutAct->setShortcut(tr("Ctrl+X"));
    connect(cutAct, SIGNAL(triggered()), this, SLOT(cut()));

    copyAct = new QAction(tr("Копировать"), this);
    copyAct->setShortcut(tr("Ctrl+C"));
    connect(copyAct, SIGNAL(triggered()), this, SLOT(copy()));

   propAct = new QAction(tr("Свойства"), this);
    propAct->setShortcut(tr("Ctrl+X"));
    connect(propAct, SIGNAL(triggered()), this, SLOT(properies()));

    deleteAct = new QAction(tr("Удалить"), this);
    deleteAct->setShortcut(tr("Ctrl+C"));
    connect(deleteAct, SIGNAL(triggered()), this, SLOT(delete_()));
}

void TMenuManager::cut()
{

}

void TMenuManager::copy()
{

}

void TMenuManager::delete_()
{

}

void TMenuManager::properies()
{

}

Все хорошо, вроде, и принципы ООП соблюдены код не дублируется в обоих виджетах. НО. В контестном меню ряд команд таких как cut, copy, delete должны быть доступны и через главное меню приложения. А главное меню формируется аналогичным образом, только в классе главного окна приложения. Там так же создаются Actions, соединяются со слотами обработчиками, в общем так же. Но будет дублирование кода.
То есть так понимаю надо сделать по аналогии классу TMenuMnager класс обрабатывающий не только котекстное меню, но и главное меню. Причем этот единый класс должен как-то принимать сообщения от виджетов требующих контекстное меню, в этих сообщениях как я уже говорил должны находиться списки объектов для которых вызывается контекстное меню. В общем я наслышался о механизме ООП, когда один объект посылает сообщения другому, но как это реализовать на практике не знаю. В данной конкретной ситуации вижу 2 варианта, если использовать этот единый класс:
1) Сделать его Singleton'ом. Инклудить этот класс в мои классы MyTreeView и MyGraphicsView и в коде обработчиков событий контестного меню писать что-то в этм роде:
Код:
TMenuManager::GetInstance()->showContextMenu(event, objects);

2) Испоьзовать механизм QT - QEvent для передачи сообщений. С ним я толком еще не разбирался, просто вижу такую возможность. В общем что можешь посоветовать?


 

Member
Статус: Не в сети
Регистрация: 18.11.2002
Откуда: не вернуться
Блин, всё мучаю свой код, опять напаролся на проблему...

Сейчас код выглядит так...

Код:
#include <stdio.h>
#include <math.h>
#include <malloc.h>

int main (void) {
   unsigned int i, j, size, *f;
   size = 1000;
   f = malloc(size);
   for(i=2; i<=size; i++) {
      if (f[i] != 1) {
         printf("%08d\n", i);
         if (i < sqrt(size)) {
            for(j=pow(i, 2); j<=size; j+=i) {
               f[j] = 1;
            }
         }
      }
   }
   free(f);
   return 1;
}

Но при "size" в 1000 он работает а в 10000 компилится нормально а при запуске глючит, пишет что-то про "Segmentation fault" или типа того...

_________________
Летели гуси-лебеди, а им навстречу - воробьи-пингвины и соловьи-страусы...


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
virus ну не хорошо,
f = malloc(size*sizeof(unsigned int));
Добавлено спустя 47 секунд
kexman прочу завтра, переосмыслю и что-нить посоветую :)

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 18.11.2002
Откуда: не вернуться
Daemon странно на одном сайте нашёл похожий пример так никаких подробностей про это не было (первый раз просто malloc юзаю, раньше он мне как-то не нужен был)

О а под FreeBSD мне GCC сказал что
Цитата:
<malloc.h> has been replaced by <stdlib.h>

Прикольно :)

_________________
Летели гуси-лебеди, а им навстречу - воробьи-пингвины и соловьи-страусы...


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Daemon
Структура программы, которую пишу в принципе ничем не отличается от типичных приложений-редакторов. Может есть какая-то блок-схема для стандартных приложений? С иерархией классов, их функциональностью. Потому что я начал смотреть сорцы QT Designer - судя по всему очень грамотно спроектированная прога. Разбираю сорцы, я не могу пройти по цепочке в поиске обработки контекстного меню, оборвался на каком-то интерфейсном классе, а далее непонятно.


 

Народ возникла проблема пишу программу на С++ у меня есть переменная типа FILE* надо удалить этот файл не зная пути.
Я в другой функции открываю файл к примеру file_=fopen("C:\1.txt","r+");
Ну вот функция возвращает только переменную file_ она естественно типа FILE* вот мне надо удалить файл связанный с переменной file_


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Что лучше использовать: RTTI или поле type для обектов с одной иерархии с общим базовым классом(поле type объявлено в нем).


 

Member
Статус: Не в сети
Регистрация: 14.03.2004
Откуда: Москва
kexman очивдно что type, но лучше использовать dynamic_cast и не забывть при необходимости ловить исключения

_________________
ФИЗТЕХ- рулез, ФАКИ - сила, Кванты тоже хорошо


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
kexman RTTI в С++ и так скуден, лучше использовать свои хаки.
nickyoz dynamic_cast для указателей не бросает исключений.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 09.08.2005
Откуда: Земля
А кто-нибудь сткруктуры понимает?

Описать стpуктуpный шаблон с именем PRICE,
содержащий следующие элементы:
- TOVAR - название товара (символьный массив);
- MAG - название магазина, в котором продается товар (символьный массив);
- STOIM - стоимость товара в рублях (тип float).
Написать программу, выполняющую следующие действия:
1 - ввод с клавиатуры данных в массив SPISOK, состоящий
из элементов типа PRICE;
2 - вывод на экpан:
- всей инфоpмации, размещенной в алфавитном порядке
по названиям товаров;
- вывод на экран информации о товаре, название которого введено с
клавиатуры; если таких товаров нет - выдать на дисплей
соответствующее сообщение.

Вот что я написал:(Сделал с помощи графики)

Код:
#include<stdio.h>
#include<graph.h>
#include<conio.h>
#include<malloc.h>

struct PRICE
{
char TOVAR[20],MAG[8];
int STOIM;
};

void main ()
{
int VVOD (FILE*);
void POTOV(struct PRICE * );
void VSE (struct PRICE *,int );
int RIS ();
struct PRICE *b;
struct _wxycoord wc, wcc;
struct videoconfig vc;
int y,s,n,t,m,i,j,k,nomer;
FILE *f;
f=fopen("7772.TXT","w+");

if (!_setvideomode(_VRES16COLOR)) {
printf("ne tanet");
/* return -1;*/ }
_getvideoconfig(&vc);
k=0;

do {
y=RIS ();

if (y==30) {
printf(" vbl xotite sozdat' novbly spisokda-0,net-1): ");
scanf("%d",&t);
if (t==0){
k=1;
n=VVOD(f);

b=calloc(n,sizeof(struct PRICE));
fseek(f,0L,SEEK_SET);
for (i=0;i<n;i++)
{
fgets(b[i].TOVAR,20,f);
fgets(b[i].MAG,8,f);
fscanf(f,"%d",&b[i].STOIM);
}
} }

if(y==78&&k==0) {printf(" nevozmogno"); getchar();}
if(y==126&&k==0) {printf(" nevozmogno"); getchar();}
if(y==78&&k==1) {POTOV(b);}
if(y==126&&k==1) {VSE (b,n);}
if(y==174) {printf(" vbI yverenbIda-0,net-1): "); scanf("%d",&m);}
}while(m!=0);

_setvideomode(_DEFAULTMODE);
}

int RIS () {
int y,s;
y=30;
s=0;
do {
if(s==56&&y!=30) y=y-48;
if(s==50&&y!=174) y=y+48;

_setcolor(0);
_rectangle(_GFILLINTERIOR,0,0,640,480);
_setcolor(1);
_rectangle(_GFILLINTERIOR,10,10,640,480);
_setcolor(2);
_rectangle(_GFILLINTERIOR,50,30,210,50);
_setcolor(3);
_rectangle(_GFILLINTERIOR,50,78,210,9;
_setcolor(4);
_rectangle(_GFILLINTERIOR,50,126,210,146);
_setcolor(5);
_rectangle(_GFILLINTERIOR,50,174,210,192);
_setcolor(0);
_rectangle(_GFILLINTERIOR,50,y,210,y+20);
_settextposition(3,9);
printf("SOZDAT'");
_settextposition(6,9);
printf("VblVESTI PO TOVARU");
_settextposition(9,9);
printf("VbIVESTI VSE \n");
_settextposition(12,9);
printf("VblXOD");
_settextposition(17,3);
printf(" vbIberete nygnoe menu pri pomoshi \n strelok na dop. klaviatyre\n");
s=getch();
} while(s!=13);
return y;
}


int VVOD (FILE *f) {
struct PRICE a;
int n,j,m;
n=0;
do {
n=n+1;
printf(" vvedite nazvanie tovara: ");
getchar();
gets(a.TOVAR);
printf(" vvedite nazvanie magazina v kotorom prodaiotsa tovar: ");
gets(a.MAG);
printf(" vvedite stoimosti tovara v rubliax: ");
scanf("%d",&a.STOIM);
fputs(a.TOVAR,f);
fprintf(f,"\n");
j=-1;
do{j=j+1;
fprintf(f,"%c",a.MAG[j]);
}while(j!=3);
fprintf(f,"\n");
fprintf(f,"%d ",a.STOIM);
printf(" prodolgit'da-0,net-1): ");
scanf("%d",&m);
}while(m!=1);
return n;
}

void POTOV (struct PRICE *a) {


}

void VSE (struct PRICE *a,int kol) {
int i;
for(i=0;i<kol;i++)
{printf(" ");
puts(a[i].TOVAR);
printf(" ");
puts(a[i].MAG);
printf(" %d\n",a[i].STOIM);}
getchar();
getchar();

}


Помогите дописать пункт 2, в частности

- вывод на экран информации о товаре, название которого введено с
клавиатуры; если таких товаров нет - выдать на дисплей соответствующее сообщение(В функции)



Заранее спасибо


 

Member
Статус: Не в сети
Регистрация: 26.01.2006
Откуда: Одесса
Вопрос конечно глуповатый... но пока что в книге ответ найти не смог (наверное плохо искал). Так вот:
Есть ли в С аналоги паскалевских функций ord и chr? Можно конечно спецификаторами формата воспользоваться, но интересуют именно функции.

_________________
Съешь еще этих мягких французских булок, да выпей чаю.


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
WerW0LF а смысл?
Код:
char a = 67;
printf("%c\n", a);

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 26.01.2006
Откуда: Одесса
Daemon
Да, как я говорил, конечно же можно при помощи спецификаторов. Собственно я так и делал. Но стало интересно, может для этого есть специальные функции?

_________________
Съешь еще этих мягких французских булок, да выпей чаю.


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
WerW0LF зачем функции, если работает простое присваивание?

_________________
Ку ку


 

Advanced member
Статус: Не в сети
Регистрация: 09.03.2004
Откуда: Кишинёв
WerW0LF Можете привести пример где вам это необходимо? :)


 

Member
Статус: Не в сети
Регистрация: 26.01.2006
Откуда: Одесса
Daemon
Уговорили :) На самом деле писал программу, и было необходимо использовать что-то вроде "chr" из Паскаля. Признаться, С я только начал учить, и не найдя в книге аналогии этой функции, использовал то присваивание, которое вы привели в качестве примера. Но думал, что так не совсем верно, потому и пытался найти "правильные" функции.

mein
Примера нет, есть лишь любопытство :)

_________________
Съешь еще этих мягких французских булок, да выпей чаю.


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Daemon nickyoz
А еще лучше оля type у каждого объекта - виртуальную функцию type() у базового класса с переопределением для каждого потомка.
Еще вопросик возник - как в C++ можно контролировать себя на утечки памяти, следить в общем за этим. Сам конечно стараюсь следить, но где-тьо все-равно возможны ошибки, приводящие к утечке. Есть ли какие-нибудь методики для этого?


 

Member
Статус: Не в сети
Регистрация: 14.01.2004
Откуда: Киев, Украина
kexman профайлеры есть для этого, типа DevPartner от бывшей Numega Studio.

_________________
Ку ку


 

Member
Статус: Не в сети
Регистрация: 12.12.2003
Откуда: Уфа
Появился вопросик - есть кусок кода:
Код:
...
#include "mappermainwindow.h"

PropertyDialog::PropertyDialog(MapperWorkBench *workBench)
   : QWidget( workBench->mainWindow() ), m_workBench(workBench)
{
...
}
...

PropertyDialog - потомок класса QWidget - в конструкторе этого класса надо передавать указатель на виджет родитель, в данном случае это - мой класс MapperMainWindow, тоже являющийся потомком QWidget. Чтобы конструктор QWidget принял в качестве аргумента MapperMainWindow* он должен знать, что этот указатель является потомком QWidget, для этого приходиться инклудить "mappermainwindow.h". Но это совершенно не нужно, так как более в данном файле класс MapperMainWindow не используется. Если не инклудить "mappermainwindow.h", то выдает справедливую ошибку - не могу преобразовать MapperMainWindow* в QWidget*. Пробовал static_cast<> - тоже не идет. Вопрос - как принудительно, без проверки типа преобразовать 1 указатель в другой(В данном случае за безопасность отвечаю сам)?
Добавлено спустя 3 минуты, 36 секунд
Только что в книжке поглядел, оказывается есть reinterpret_cast<>. Круто :)


Показать сообщения за:  Поле сортировки  
Начать новую тему Новая тема / Ответить на тему Ответить  Сообщений: 1730 • Страница 37 из 87<  1 ... 34  35  36  37  38  39  40 ... 87  >
-

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 2


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Перейти:  
Создано на основе phpBB® Forum Software © phpBB Group
Русская поддержка phpBB | Kolobok smiles © Aiwan