Модераторы: bsa

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Шабл.класс "Матрица".Помогите сделать пожалуйста! 
V
    Опции темы
yorgan
  Дата 5.6.2008, 16:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Всем привет.
Есть такое задание:
Нужно написать шаблонный класс "матрица", в котором будет:
1. конструктор (матрица размером 10 на 20).
2. деструктор.
3. нахождение детерминанта матрицы (определителя).
4. нахождение обратной матрицы.
5. Вывод элемента [][];
6. Умножение матрицы А на B.

У меня такие вопросы:
Как выделять в конструкторе память динимически под матрицу заданной размерности (соответственно как освобождать помять в деструкторе)?
Как находить определитель матрицы (на сколько я понимаю это будет рекурсивная функция)? Если была бы матрица 3 на 3, я нашел бы без проблем, а вот 10 н 20... не знаю :(
Вывод элемента... вот тут я не очень понял. Если просто написать функцию-член, которая будет по заданным [i][j] выводить на экран элемент, то это просто, а если нужо переопределить операцию [][]...???

Помогите пожалуйста.
PM MAIL   Вверх
dragomir
Дата 5.6.2008, 17:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 24
Регистрация: 28.1.2007
Где: Брянск

Репутация: нет
Всего: нет



Цитата(yorgan @  5.6.2008,  16:56 Найти цитируемый пост)
Как находить определитель матрицы (на сколько я понимаю это будет рекурсивная функция)? Если была бы матрица 3 на 3, я нашел бы без проблем, а вот 10 н 20... не знаю :(


Вроде бы методом Гаусса можно найти определитель любой матрицы
PM MAIL   Вверх
yorgan
Дата 5.6.2008, 17:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



На сколько я помню курс линейной алгебры... методом Гаусса ищется корни СЛАУ (систем линейных алгебраических уравнений)
PM MAIL   Вверх
bronislav
Дата 5.6.2008, 17:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  5.6.2008,  15:56 Найти цитируемый пост)
Как находить определитель матрицы (на сколько я понимаю это будет рекурсивная функция)? Если была бы матрица 3 на 3, я нашел бы без проблем, а вот 10 н 20... не знаю :(

Насколько я знаю можно найти (без до определения) только определитель квадратной матрицы.
Посмотри тут.

Добавлено через 35 секунд
Цитата(yorgan @  5.6.2008,  16:39 Найти цитируемый пост)
методом Гаусса ищется корни СЛАУ (систем линейных алгебраических уравнений) 

Именно так

Добавлено через 4 минуты и 2 секунды
и тут


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
IKM2007
Дата 5.6.2008, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Зима близко
**


Профиль
Группа: Участник
Сообщений: 702
Регистрация: 26.4.2008
Где: olmedreca

Репутация: 3
Всего: 40



Цитата(yorgan @  5.6.2008,  16:56 Найти цитируемый пост)
Как выделять в конструкторе память динимически под матрицу заданной размерности (соответственно как освобождать помять в деструкторе)?

Код

#include <assert.h>
class Matrix
{
public:
Matrix(int=10,int=20);//default constructor
~Matrix();
private:
int    **a;
int n;
int m;
};
Matrix::Matrix(int x,int y)//constructor
{
    n=x;
    m=y;
a=new int *[n];
assert(a);
for(int i=0;i<n;i++)
{a[i]=new int [m];
assert(a[i]);
}

for(i=0;i<n;i++)
for(int j=0;j<m;j++)
a[i][j]=0;
}
Matrix::~Matrix()//destructor
{
for(int i=0;i<n;i++)
delete [] a[i];
delete [] a;
}

На остальное нет ни идей,ни времени(Завтра экзамен).


--------------------
"К чёрту обстоятельства, я создаю возможности."
Брюс Ли
PM MAIL Skype   Вверх
bronislav
Дата 5.6.2008, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  5.6.2008,  15:56 Найти цитируемый пост)
конструктор (матрица размером 10 на 20).

Я бы рекомендовал размер матрицы задавать в параметрах конструктора. А их можно сделать со значениями по умолчанию, если тебе так нужен размер 10 x 20.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
bronislav
Дата 5.6.2008, 18:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



IKM2007,
Цитата(yorgan @  5.6.2008,  15:56 Найти цитируемый пост)
Нужно написать шаблонный класс "матрица", в котором будет:


Ключевое слово тут шаблонный.

Например вот так:

Код

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <exception>

template < class T >
class matrix
{
private:
    T** data; // массив элементов матрицы
    int rows; // количество строк
    int cols; // количество столбцов
public:
    matrix( int _rows = 10, int _cols = 20 );
    ~matrix( );
    
    
};

template < class T >
matrix< T >::matrix( int _rows, int _cols )
: rows( _rows ), cols( _cols )
{
    try
    {
        data = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            data[ i ] = new T [ cols ];
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::matrix(" << _rows << ", " << _cols << "): " << e.what() << std::endl;
    }
}

template < class T >
matrix< T >::~matrix()
{
    try
    {
        for( int i = 0; i < rows; i++ )
        {
            if( data[ i ] != NULL )
                delete [] data[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] data;
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::~matrix( ): " << e.what() << std::endl;
    }
}

#endif /*MATRIX_H_*/


А использовать так:
Код

#include "matrix.h"

int main()
{
    matrix< int >(5,6);
    return 0;
}




--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
Dmi3ev
Дата 5.6.2008, 18:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



Код

float **matrix;
matrix = new *[n];
for (int j=0; j<m; j++)
 matrix[j]=new float[n];

можно так создавать матрицу динамически, как вариант. а вообще не понятно зачем это делать, если размерность заранее известна?

Добавлено через 1 минуту и 51 секунду
а вот так если:
Код

class Matrix
{
public:
 Matrix (){};
 void Set(float a11, float a12, float a13, float a21, float a22, float a23, float a31, float a32, float a33)
  {
   m[0][0]=a11;
   m[0][1]=a12;
   m[0][2]=a13;
   m[1][0]=a21;
   m[1][1]=a22;
   m[1][2]=a23;
   m[2][0]=a31;
   m[2][1]=a32;
   m[2][2]=a33;
  };
 float Determ()
  {
   float det=(m[0][0]*m[1][1]*m[2][2])+(m[0][1]*m[1][2]*m[2][0])+
             (m[2][0]*m[0][2]*m[2][1])-(m[0][1]*m[1][0]*m[2][2])-
             (m[0][0]*m[1][2]*m[2][1])-(m[0][2]*m[1][1]*m[2][0]);
   return det;
  };

 ~Matrix(){};
private:
 float m[3][3];
};



--------------------

PM MAIL   Вверх
bronislav
Дата 5.6.2008, 18:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(Dmi3ev @  5.6.2008,  17:06 Найти цитируемый пост)
если размерность заранее известна?

А что если размерность заранее известна, то ее лучше в стеке создать? А если экземпляров класса будет 100-200.
ИМХО такой подход не есть гуд. 


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 5.6.2008, 18:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Пока писал, уже несколько людей ответили. Сейчас буду разбираться. Всем большое спасибо за желание помочь!!!  smile 

Цитата(bronislav @  5.6.2008,  17:40 Найти цитируемый пост)
Насколько я знаю можно найти (без до определения) только определитель квадратной матрицы.
Посмотри тут.

Да, вы правы.  Сейчас еще посмотрел учебник по математике. Значит преподаватель ошибся.

IKM2007, спасибо. Уже что-то... а то голова гудит, не знаю даже с чего начать. 

Тогда вопрос таков: как найти детерминант квадратной матрицы 10 на 10? 
Мне бы посмотреть на код, где вычисляется хотя бы определитель матрицы 4 на 4 (как я понял есть только один метод нахождения определителя матрицы N-го порядка -  с помощью суммы произведений элементов некоторого ряда на соотвествующие им алгебраические дополнения).

Это сообщение отредактировал(а) yorgan - 5.6.2008, 18:14
PM MAIL   Вверх
Dmi3ev
Дата 5.6.2008, 18:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1698
Регистрация: 28.11.2007

Репутация: 13
Всего: 41



ну если говорить о матрице 4*4, то тогда формула определителя такова:
det A=a11*(-1)^(1+1)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a11))+
          a12*(-1)^(1+2)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a12))+
           a13*(-1)^(1+3)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a13))+
           a14*(-1)^(1+4)*(det (та же матрица, только надо вычеркнуть строку и столбец где расположен a12))
а как считать определитель для матрицы 3*3, которая получается в скобках я написал в описании класса Matrix (метод Determ), я считал по правилу Саррюса

Добавлено через 3 минуты и 44 секунды
Цитата

А что если размерность заранее известна, то ее лучше в стеке создать? А если экземпляров класса будет 100-200.
ИМХО такой подход не есть гуд. 

вообще да, но если 10 на 20 и в массиве хранятся числа, а не большие боъекты , то, мне кажется, по барабану


--------------------

PM MAIL   Вверх
bronislav
Дата 5.6.2008, 19:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(Dmi3ev @  5.6.2008,  17:25 Найти цитируемый пост)
вообще да, но если 10 на 20 и в массиве хранятся числа, а не большие боъекты , то, мне кажется, по барабану 

Мне кажется, что даже для небольших матриц это не хорошая практика ибо привыкнешь  smile 


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
  Дата 5.6.2008, 21:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Функции нахождения детерминатна и обратной матрицы, ввода матриц и перемножения матриц:
Код

double determinant(int **a, int N) 

  int i,j; 
  int **matr1; 
  double determ=0; 

    matr1=new int*[N-1]; 
 
    for(i=0;i<N;i++) 
    { 
      for(j=0;j<N-1;j++) 
     { 
      if(j<i)   {matr1[j]=a[j];} 
      else      {matr1[j]=a[j+1];} 
      } 
      determ+=pow(-1,(i+j))*determinant(matr1,N-1)*a[i][N-1]; 
    } 
    delete matr1; 
  } 
 
  return determ; 
}

////////////

void show_obratnaya_matrica(int **a, int N)
{
    matr=new int*[N];
   double det = 0; 
   int i, j, k;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = a[j*N + i];
        }
    }
  det = determinant(a,N);

    for( i = 0; i < N; i++)
    {
        cout << "\n";
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = matr[j*N + i] * (1\det);
            cout  << matr[i*N + j];
        }
    }
 delete matr;
}
/////////////
void vvodmatrAandB(int **a, int **b, int  N)
{
   int i, j;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            cin >> a[i*N + j];
            cin >> b[i*N + j];
     
        }
    }
    
}

////////////
void peremnojehieAB(int **a, int **b, int **c, int  N))
{
     for(i=0;i<N;I++)   
    {
        for(j=0;j<N;j++) 
        {
         c[i*N + j]=0;
         for(k=0;k<N;k++) 
         {
              C[i*N + j]+=a(i*N + k)*b(k*N + j); 
          }
      }
  }
}



У меня еще пока плохо с ООП в целом и с шаблонами в частности, может кто-то может подсказать как притулить эту функцию как метода класса к коду bronislav'а:


Код

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <exception>

template < class T >
class matrix
{
private:
    T** data; // массив элементов матрицы
    int rows; // количество строк
    int cols; // количество столбцов
public:
    matrix( int _rows = 10, int _cols = 10 );
    ~matrix( );
    
    
};

template < class T >
matrix< T >::matrix( int _rows, int _cols )
: rows( _rows ), cols( _cols )
{
    try
    {
        data = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            data[ i ] = new T [ cols ];
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::matrix(" << _rows << ", " << _cols << "): " << e.what() << std::endl;
    }
}

template < class T >
matrix< T >::~matrix()
{
    try
    {
        for( int i = 0; i < rows; i++ )
        {
            if( data[ i ] != NULL )
                delete [] data[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] data;
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::~matrix( ): " << e.what() << std::endl;
    }
}

#endif /*MATRIX_H_*/


И если не сложно, то не могли бы объяснить что есть exception.h  и почему такой синтаксис в этой строке: : rows( _rows ), cols( _cols )?

Это сообщение отредактировал(а) yorgan - 5.6.2008, 23:39
PM MAIL   Вверх
bronislav
Дата 6.6.2008, 09:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  5.6.2008,  20:47 Найти цитируемый пост)
И если не сложно, то не могли бы объяснить что есть exception.h  и почему такой синтаксис в этой строке: : rows( _rows ), cols( _cols )?

Это код проводит инициализацию членов данных класса параметрами конструктора.

Цитата(yorgan @  5.6.2008,  20:47 Найти цитируемый пост)
не могли бы объяснить что есть exception.h 

Во первых просто exception без h.
Это заголовочный файл про обработку исключений. Вопросы по обработке исключений уже много раз поднимались на форуме, воспользуйся поиском или посмотри вот в этой теме например.

Добавлено через 1 минуту и 40 секунд
Да и умножение и ввод матриц можно, даже скорее нужно реализовать через перегрузку операторов.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 6.6.2008, 10:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Вот что-то навоял. Посмотрите пожалуйста в чем ошибки?

Код

#ifndef MATRIX_H_
#define MATRIX_H_

#include <iostream>
#include <exception>
#define N 10

template < class T >
class matrix
{
private:
    T** a, b, c; // массив элементов матриц
    int rows; // количество строк
    int cols; // количество столбцов
public:
    matrix( int _rows = 10, int _cols = 10 );
    ~matrix( );
    void vvodmatrAandB(int, int, int)
    T determinant(int, int);
    void peremnojehieAB(int, int, int, int)
    
    
};

template < class T >
matrix< T >::matrix( int _rows, int _cols )
: rows( _rows ), cols( _cols )
{
    try
    {
        a = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            a[ i ] = new T [ cols ];
        b = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            b[ i ] = new T [ cols ];
        c = new T* [ rows ];
        for( int i = 0; i < rows; i++ )
            c[ i ] = new T [ cols ];
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::matrix(" << _rows << ", " << _cols << "): " << e.what() << std::endl;
    }
}

template < class T >
matrix< T >::~matrix()
{
    try
    {
        for( int i = 0; i < rows; i++ )
        {
            if( a[ i ] != NULL )
                delete [] a[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] a;
        

        for( int i = 0; i < rows; i++ )
        {
            if( a[ i ] != NULL )
                delete [] b[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] b;

        for( int i = 0; i < rows; i++ )
        {
            if( a[ i ] != NULL )
                delete [] c[ i ];
            else
                break;
        }
        if( data != NULL )
            delete [] c;
    }
    catch( std::exception e )
    {
        std::cerr << "matrix::~matrix( ): " << e.what() << std::endl;
    }
}

template < class T >
void matrix< T >:: vvodmatrAandB(int **a, int **b, int  N)
{
   int i, j;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            cin >> a[i*N + j];
            cin >> b[i*N + j];
     
        }
    }
    
}


template < class T >
T matrix < T >:: determinant(int **a, int N)

  int i,j; 
  int **matr1; 
  double determ=0; 

    matr1=new int*[N-1]; 
 
    for(i=0;i<N;i++) 
    { 
      for(j=0;j<N-1;j++) 
     { 
      if(j<i)   {matr1[j]=a[j];} 
      else      {matr1[j]=a[j+1];} 
      } 
      determ+=pow(-1,(i+j))*determinant(matr1,N-1)*a[i][N-1]; 
    } 
    delete matr1; 
  } 
 
  return determ; 
}

template < class T >
void matrix< T >:: show_obratnaya_matrica(int **a, int N)
{
    matr=new int*[N];
   double det = 0; 
   int i, j, k;
    for( i = 0; i < N; i++)
    {
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = a[j*N + i];
        }
    }
  det = determinant(a,N);

    for( i = 0; i < N; i++)
    {
        cout << "\n";
        for( j = 0; j < N; j++)
        {
            matr[i*N + j] = matr[j*N + i] * (1\det);
            cout  << matr[i*N + j];
        }
    }
 delete matr;
}



#endif /*MATRIX_H_*/

PM MAIL   Вверх
bronislav
Дата 6.6.2008, 10:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Класс matrix описывает одну матрицу, а для работы с несколькими матрицами создается несколько экземпляров класса.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 6.6.2008, 10:38 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Как?
Не могу понять в чем именно ошибка... ООП практически не знаю :(
PM MAIL   Вверх
bronislav
Дата 6.6.2008, 10:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  6.6.2008,  09:29 Найти цитируемый пост)
T** a, b, c; // массив элементов матриц

Зачем в классе 3 массива для матриц? Вам надо использовать 3 матрицы?

Тогда переопределяем оператор умножения для класса matrix и умножаем матрицы так:

Код

matrix a(5), b(5), c(5);
cin >> a >> b;
c = a * b;



--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 6.6.2008, 10:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Это все, что не правильно в коде?
Матрицы три, т.к. нужно разные действия делать: умножать 2 матрицы друг на друга, результат помещать в третью.
А как переопределить оператор умножения?
PM MAIL   Вверх
bronislav
Дата 6.6.2008, 10:53 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Вообще-то не мешало бы воспользоваться поиском на тему "Перегрузка операций"

И можно посмотреть тут.

Это сообщение отредактировал(а) bronislav - 6.6.2008, 10:54


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 6.6.2008, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



времени уже нету. Через 40 минут нужно  уже выезжать в универ :(
P.s. в коде больше ошибок\неточностей нету?
PM MAIL   Вверх
bronislav
Дата 6.6.2008, 10:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  6.6.2008,  09:49 Найти цитируемый пост)
Это все, что не правильно в коде?


Ну по аналогии с умножение надо переделать функции ввода и др.

Добавлено через 1 минуту и 24 секунды
Цитата(yorgan @  6.6.2008,  09:55 Найти цитируемый пост)
времени уже нету. Через 40 минут нужно  уже выезжать в универ :(

Оно компилируется? Значит работает, но будь готов к тому, что преподаватель отрицательно отреагирует на такой код.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 6.6.2008, 11:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Не компилится :(
Ругается на переменную i в каждой функции - типа много раз она уже объявлена.
А вот обращение по [][] к элементу матрицы - преподаватлеь имел ввиду просто написать функцию, которая будет выводить элементы матрицы по указанным i и j или нужно переопределять операцию [][] ???? 
PM MAIL   Вверх
bsa
Дата 6.6.2008, 11:06 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Я бы порекомендовал в качестве параметров шаблона задавать еще и размерность матрицы:
Код
template<unsigned cols = 3, unsigned rows = 3, typename Type = double>
class Matrix
{
public:
   Matrix();
protected:
   Type data[cols][rows];
};
Недостатки:
1. автоматические матрицы занимают много места в стеке (а зачем много автоматических матриц?)
Преимущества:
1. высокая скорость создания объекта
2. не надо заморачиваться с конструктором копирования
3. высокая скорость доступа к элементам (компилятор генерирует код оптимизированный под конкретные значения размерностей)
4. возможность написания легко оптимизируемых алгоритмов расчета определителя
5. возможность организации на стадии компиляции проверки на корректность арифметических операций (т.е. нельзя перемножить матрицу 4x4 на 3x3), как-то так:
Код
template<unsigned cols, unsigned rows, unsigned cols2, typename Type>
Matrix<cols2, rows, Type> operator*(const Matrix<cols, rows, Type>&m1, const Matrix<cols2, cols, Type> &m2)
{
    Matrix<cols2, rows, Type> result;
    ....
    return result;
}

PM   Вверх
bronislav
Дата 6.6.2008, 12:27 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(bsa @  6.6.2008,  10:06 Найти цитируемый пост)
Я бы порекомендовал в качестве параметров шаблона задавать еще и размерность матрицы:

 smile Мда, а я и не знал, что в качестве параметров шаблона можно задавать числа. =(

Это сообщение отредактировал(а) bronislav - 6.6.2008, 12:27


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
andrew_121
Дата 6.6.2008, 12:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 10
Всего: 33



yorgan: То что ты навоял - работает?
На всякий случай держи вот этот шаблон.
Сам юзаю в проекте по разложению звука на спектр.

Код

template<typename T, typename SliceType = std::slice> class CSlice_iter {
public:

    CSlice_iter( std::valarray<T>* vv, SliceType ss )
        :mValarray( vv ), mSlice( ss ), mCurrIdx( 0 )
    {
    }

    CSlice_iter end() {
        CSlice_iter    t = *this;
        t.mCurrIdx = mValarray.size();
        return t;
    }

    CSlice_iter& operator++() {
        mCurrIdx++;
        return *this;
    }

    CSlice_iter operator++( int ) {
        CSlice_iter    t = *this;
        mCurrIdx++;
        return t;
    }

    T operator[]( unsigned int idx ) {
        return ref( mCurrIdx = idx );
    }

    T operator()( unsigned int idx ) {
        return ref( mCurrIdx = idx );
    }

    T operator *() {
        return ref( mCurrIdx );
    }


private:

    std::valarray<T>* mValarray;
    SliceType            mSlice;
    unsigned int        mCurrIdx; // index of current element

    inline T& ref( unsigned int i ) const {
        return ( *mValarray )[mSlice.start() + i * mSlice.stride()];
    }
};

template<typename T, typename SliceType> bool operator==( const CSlice_iter<T, SliceType>& p, const CSlice_iter<T, SliceType>& q ) {
    return p.mCurrIdx == q.mCurrIdx && p.s.stride() == q.s.stride() && p.s.start() == q.s.start();
}

template<typename T, typename SliceType> bool operator!=( const CSlice_iter<T, SliceType>& p, const CSlice_iter<T, SliceType>& q ) {
    return !( p == q );
}

template<typename T, typename SliceType> bool operator<( const CSlice_iter<T, SliceType>& p, const CSlice_iter<T, SliceType>& q ) {
    return p.curr < q.curr && p.s.stride() == q.s.stride() && p.s.start() == q.s.start();
}

/***************************************************************************/

template<typename T, typename SliceType = std::slice> class Slice_iter {
public:

    Slice_iter( std::valarray<T>* vv, SliceType ss )
        :mValarray( vv ), mSlice( ss ), mCurrIdx( 0 )
    {
    }

    Slice_iter end() {
        Slice_iter    t = *this;
        t.mCurrIdx = mValarray.size();
        return t;
    }

    Slice_iter& operator++() {
        mCurrIdx++;
        return *this;
    }

    Slice_iter operator++( int ) {
        Slice_iter    t = *this;
        mCurrIdx++;
        return t;
    }

    T& operator[]( unsigned int idx ) {
        return ref( mCurrIdx = idx );
    }

    T& operator()( unsigned int idx ) {
        return ref( mCurrIdx = idx );
    }

    T& operator *() {
        return ref( mCurrIdx );
    }


private:

    std::valarray<T>* mValarray;
    SliceType            mSlice;
    unsigned int        mCurrIdx; // index of current element

    inline T& ref( unsigned int i ) const {
        return ( *mValarray )[mSlice.start() + i * mSlice.stride()];
    }
};

template<typename T, typename SliceType> bool operator==( const Slice_iter<T, SliceType>& p, const Slice_iter<T, SliceType>& q ) {
    return p.mCurrIdx == q.mCurrIdx && p.s.stride() == q.s.stride() && p.s.start() == q.s.start();
}

template<typename T, typename SliceType> bool operator!=( const Slice_iter<T, SliceType>& p, const Slice_iter<T, SliceType>& q ) {
    return !( p == q );
}

template<typename T, typename SliceType> bool operator<( const Slice_iter<T, SliceType>& p, const Slice_iter<T, SliceType>& q ) {
    return p.curr < q.curr && p.s.stride() == q.s.stride() && p.s.start() == q.s.start();
}

/***************************************************************************/

template<typename T> class Matrix {
    std::valarray<T>* pData;
    unsigned int        mdim1;
    unsigned int        mdim2;

public:

    Matrix( unsigned int x, unsigned int y ) {
        mdim1 = x;
        mdim2 = y;

        pData = new std::valarray<T>( x * y );
    }

    Matrix( const Matrix& m );

    Matrix& operator=( const Matrix& m );

    ~Matrix() {
        delete pData;
    }

    unsigned int size() const {
        return mdim1 * mdim2;
    }

    unsigned int dim1() const {
        return mdim1;
    }

    unsigned int dim2() const {
        return mdim2;
    }

    inline T& operator()( unsigned int i, unsigned int j ) {
        return row( i )[j];
    }

    inline T operator()( unsigned int i, unsigned int j ) const {
        return row( i )[j];
    }


    inline Slice_iter<T> row( unsigned int i ) {
        return Slice_iter<T>( pData, std::slice( i * mdim2, mdim2, 1 ) );
    }

    inline CSlice_iter<T> row( unsigned int i ) const {
        return CSlice_iter<T>( pData, std::slice( i * mdim2, mdim2, 1 ) );
    }

    inline Slice_iter<T> column( unsigned int j ) {
        return Slice_iter<T>( pData, std::slice( j, mdim1, mdim2 ) );
    }

    inline CSlice_iter<T> column( unsigned int j ) const {
        return CSlice_iter<T>( pData, std::slice( j, mdim1, mdim2 ) );
    }

    Slice_iter<T> operator[]( unsigned int i ) {
        return row( i );
    }

    CSlice_iter<T> operator[]( unsigned int i ) const {
        return row( i );
    }

    Matrix& operator *( T d ) {
        ( *pData ) *= d;

        return *this;
    }

    inline std::valarray<T> operator *( const std::valarray<T>& v ) {
        std::valarray<T>    res( dim1() );

        for ( int i = 0; i < dim1(); i++ ) {
            res( i ) = mul( row( i ), v );
        }

        return res;
    }



    std::valarray<T>& array() {
        return *pData;
    }

private:

    inline T mul( const std::valarray<T>& v1, const std::valarray<T>& v2 ) {
        T    res = 0;

        for ( int i = 0; i < v1.size(); i++ ) {
            res += v1[i] * v2[i];
        }

        return res;
    }
};



Так как шаблон выдран из проекта, возможны ошибки компиляции. Думаю ты разберешся...

Удачи.

Это сообщение отредактировал(а) andrew_121 - 6.6.2008, 15:07

Присоединённый файл ( Кол-во скачиваний: 6 )
Присоединённый файл  matrix.h 5,11 Kb


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
andrew_121
Дата 6.6.2008, 13:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Кодофей
****


Профиль
Группа: Завсегдатай
Сообщений: 3448
Регистрация: 3.1.2008

Репутация: 10
Всего: 33



Да, и еще...
Остальной функционал набросай сам. Методы все есть, теории в инете то же.


--------------------
Удалил аккаунт. Прощайте!
PM MAIL   Вверх
yorgan
Дата 8.6.2008, 14:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Спасибо за помощь. Буду разбираться (нужно переопределить еще операцию умножения - для умножения матриц и взятие элемента через операцию [][] )
Преподватель спросил: а можно ли этот файл ( шаблонный класс "матрица") сделать библиотекой? Если нельзя, то почему?

Это сообщение отредактировал(а) yorgan - 8.6.2008, 14:15
PM MAIL   Вверх
bronislav
Дата 8.6.2008, 20:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Для каждого набора аргументов шаблона на этапе компиляции содается свой класс, который уже и обрабатывается компилятором.

Библиотекой сделать можно, НО при условии его не доступности вне библиотеки. Т.е. использование только для внутренних нужд.

Возможно ошибаюсь.


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
  Дата 8.6.2008, 21:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Вот код:

Код

#include <stdlib.h>
#include <mem.h>    // для setmem()
#include <fstream.h>
#include <math.h>
typedef unsigned char dim;
template <class VARTYPE> class Matrix {
typedef Matrix Vector;
private:
VARTYPE *matr;     // указатель на массив матрицы
dim m,n;                    // размеры матрицы
public:
// конструкторы и деструкторы:
Matrix() { matr=(VARTYPE*)0; m=n=0; }
Matrix(dim,dim=1); // Обычный конструктор
Matrix(const Matrix<VARTYPE>&); // Конструктор копирования
~Matrix() { delete [ ]matr; }
// доступ к элементам матрицы
dim size_row() { return m; }  // число строк
dim size_col() { return n; }     // число столбцов
VARTYPE& operator() (dim x) const { return (*this)(x,0); } // элементу
// перегруженные операции и функции:
Matrix<VARTYPE>& operator=(const Matrix<VARTYPE>&);
Matrix<VARTYPE>& operator=(const VARTYPE&);
Matrix<VARTYPE> operator^(int);   // возведение в степень
Matrix<VARTYPE> operator!();      // транспонирование
VARTYPE determ();   // определитель матрицы
VARTYPE vmodul();   // модуль вектора
Matrix& Gauss(dim,dim); // преобразование по Гауссу
// (для получ. обратной и единичной матрицы)
// (для получ. верхнетреугольной матрицы)
Matrix  minor(dim,dim);  // возвращает указ. минор матрицы
Vector  line(dim i)       // возвращает вектор-строку матрицы
{ return extract(1,n,i,0); }
Vector  column(dim j)     // возвращает вектор-столбец матрицы
{ return extract(m,1,0,j); }
VARTYPE& operator() (dim,dim) const;
// доступ к
Matrix<VARTYPE>& operator<<=(const Matrix &A) { return newsize(A.m,A.n)=A; }
// безусловное приравнивание матриц
Matrix<VARTYPE>& insert(const Matrix&, dim=0, dim=0);
// вставить часть матрицы
Matrix<VARTYPE> extract(dim, dim, dim=0, dim=0);                      //извлечь часть матрицы
Matrix<VARTYPE>& newsize(dim, dim=1);                         //установить новые размеры
void swap_line(dim, dim);
//обмен строками матрицы
void swap_column(dim, dim);
// обмен столбцами матрицы
friend Matrix<VARTYPE> operator+(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);   //A-B
friend Matrix<VARTYPE> operator-(const Matrix<VARTYPE>&,const
Matrix<VARTYPE>&);    //A-B
friend Matrix<VARTYPE> operator*(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);   //A*B
friend Matrix operator*(const double&,const Matrix<VARTYPE>&);  //k*A
friend Matrix operator*(const Matrix<VARTYPE>&, const double&); //A*k
friend ostream& operator<<(ostream&,Matrix<VARTYPE>&);// потоковый вывод матрицы
friend int operator>>(istream&,Matrix<VARTYPE>&);// потоковый ввод существ. матрицы
// 0 - без. ошибок, 1 - была ошибка
dim read(ifstream&);   // файловое чтение и запись матрицы
dim write(ofstream&);            // в ее внутреннем, двоичном представлении.
friend VARTYPE operator %(const Matrix<VARTYPE>&,const Matrix<VARTYPE>&);
//Функция ошибок
void ERROR_MATRIX(dim) const;
};
// Реализация класса матриц
template <class VARTYPE>
Matrix<VARTYPE>::Matrix(dim M, dim N)
{
m=M;
n=N;
matr=new VARTYPE[m*n];
if(!matr) ERROR_MATRIX(1);
setmem(matr,sizeof(VARTYPE)*m*n,0);
}
template <class VARTYPE>
Matrix<VARTYPE>::Matrix(const Matrix<VARTYPE> &M_Obj)  //Конструктор копирования
{
m=M_Obj.m;
n=M_Obj.n;
matr=new VARTYPE[m*n];
if(!matr) ERROR_MATRIX(1);
movmem(M_Obj.matr, matr, sizeof(VARTYPE)*m*n);
}
template <class VARTYPE>
Matrix<VARTYPE>& Matrix<VARTYPE>::operator=(const Matrix<VARTYPE> &M_Obj)
{
m=M_Obj.m;
n=M_Obj.n;
matr=new VARTYPE[m*n];
if(!matr) ERROR_MATRIX(1);
movmem(M_Obj.matr,matr,sizeof(VARTYPE)*m*n);
return *this;
}
template <class VARTYPE>
Matrix<VARTYPE>& Matrix<VARTYPE>::operator=(const VARTYPE &f)
{
for(int i=0,j;i<m;i++) for(j=0;j<n;j++)
if(i==j) (*this)(i,j)=f;
else (*this)(i,j)=0;
return *this;
}
template <class VARTYPE>
Matrix<VARTYPE> Matrix<VARTYPE>::operator^(int q) // Степень
{
if (q>0)
{
for(Matrix M=*this; q>1; q--)
M=M*(*this);
return M;
}
if (q!=-1) ERROR_MATRIX(3);
// вычисление обратной метoдом преобразований Гаусса
if (n!=m)  ERROR_MATRIX(4);
Matrix M(m,2*n);
M.insert(*this);
for(int i=0;i<M.m;i++)
M(i,i+M.m)=1;
for(i=0;i<M.m;i++)
M.Gauss(i,i);
return M.extract(M.m,M.m,0,M.m);
}
template <class VARTYPE>
Matrix<VARTYPE> Matrix<VARTYPE>::operator!()  // Транспозиция
{ Matrix<VARTYPE> A(n,m);
for(int i=0, j; i<m; i++)
for(j=0; j<n; j++)
A(j,i)=(*this)(i,j);
return A;
}
template <class VARTYPE>
VARTYPE Matrix<VARTYPE>::determ() // рекурсивно находит определитель матрицы
{
if (n!=m) ERROR_MATRIX(4);
if (n==1)
return (*this)(0,0);
for(int i=0; i<m; i++)
if ((*this)(i,0))
{
static Matrix<VARTYPE> M;
M <<= *this;
VARTYPE d=M(i,0)*(i%2?-1:1);
return d*M.Gauss(i,0).minor(i,0).determ();
}
return 0.0;
}
template <class VARTYPE>
VARTYPE Matrix<VARTYPE>::vmodul()      // Модуль вектора
{
VARTYPE d=0;
if (n!=1) ERROR_MATRIX(9);
static Matrix<VARTYPE> M;
M <<= *this;
for(int i=0; i<m; i++)
d=d+M(i,0)*M(i,0);
return sqrt(d);
}
template <class VARTYPE>
Matrix<VARTYPE>& Matrix<VARTYPE>::Gauss(dim M, dim N)
{
Matrix<VARTYPE>& A=*this;
if (!A(M,N))  ERROR_MATRIX(5);
for(int i=0,j;i<m;i++)
for(j=0;j<n;j++)
if (i!=M && j!=N)
A(i,j)-=A(M,j)*A(i,N)/A(M,N);
for(j=0;j<n;j++)
if (j!=N)
A(M,j)/=A(M,N);
for(i=0;i<m;i++)
A(i,N)=0;
A(M,N)=1;
return *this;
}
template <class VARTYPE>
Matrix<VARTYPE> Matrix<VARTYPE>::minor(dim M, dim N)         // возвращ. матрицу без
{
// строки y и столбца x
Matrix<VARTYPE> A(m-1,n-1);
for(int i=0,in=0,j,jn;i<m;i++)
if (i!=M)
{
for(j=0,jn=0;j<n;j++)
if (j!=N)
A(in,jn++)=(*this)(i,j);
in++;
}
return A;
}
template <class VARTYPE>   // вставка
Matrix<VARTYPE>& Matrix<VARTYPE>::insert(const Matrix<VARTYPE> &A, dim M, dim N)
{
if (M+A.m>m || N+A.n>n)  ERROR_MATRIX(6);
for(int i=0, j; i<A.m; i++)
for(j=0; j<A.n; j++)
(*this)(i+M,j+N)=A(i,j);
return *this;
}
template <class VARTYPE>   // извлечение
Matrix<VARTYPE> Matrix<VARTYPE>::extract(dim LM, dim LN, dim M, dim N)
{
if (M+LM>m || N+LN>n)  ERROR_MATRIX(7);
Matrix<VARTYPE> A(LM,LN);
for(int i=0, j; i<LM; i++)
for(j=0; j<LN; j++)
A(i,j)=(*this)(i+M,j+N);
return A;
}
template <class VARTYPE>
VARTYPE& Matrix<VARTYPE>::operator() (dim M, dim N) const
{ return *(matr+n*M+N); }
template <class VARTYPE>
Matrix<VARTYPE> operator+(const Matrix<VARTYPE> &A, const Matrix<VARTYPE>&B)
{
Matrix<VARTYPE> C=A;
for(int i=0,j; i<A.m; i++)
for(j=0; j<A.n; j++)
C(i,j)+=B(i,j);
return C;
}
template <class VARTYPE>
Matrix<VARTYPE> operator-(const Matrix<VARTYPE> &A, const Matrix<VARTYPE> &B)
{
Matrix<VARTYPE> C=A;
for(int i=0, j; i<A.m; i++)
for(j=0;j<A.n;j++)
C(i,j)-=B(i,j);
return C;
}
template <class VARTYPE>
Matrix<VARTYPE> operator*(const Matrix<VARTYPE> &A,const Matrix<VARTYPE> &B)
{
Matrix<VARTYPE> C(A.m,B.n);
if (A.n!=B.m)
{
if(A.m==3 && A.n==1 && B.m==3 && B.n==1)
{
C(0)=A(1)*B(2)-A(2)*B(1);
C(1)=A(2)*B(0)-A(0)*B(2);
C(2)=A(0)*B(1)-A(1)*B(0);
}
else
A.ERROR_MATRIX(2);
}
else
{
for(int i=0,j,k;i<C.m;i++)
for(j=0;j<C.n;j++)
for(k=0;k<A.n;k++)
C(i,j)+=A(i,k)*B(k,j);
}
return C;
}
template <class VARTYPE>//умножение числа на матрицу
Matrix<VARTYPE> operator*(const double &f,const Matrix<VARTYPE> &A)
{
Matrix<VARTYPE> B=A;
for(int i=0,j;i<A.m;i++)
for(j=0;j<A.n;j++)
B(i,j)*=f;
return B;
}
template <class VARTYPE>// умножение матрицы на число
Matrix<VARTYPE> operator*(const Matrix<VARTYPE> &A, const double &f)
{
Matrix<VARTYPE> B=A;
for(int i=0,j;i<A.m;i++)
for(j=0;j<A.n;j++)
B(i,j)*=f;
return B;
}
template <class VARTYPE>
Matrix<VARTYPE>& Matrix<VARTYPE>::newsize(dim M, dim N)
{ delete [] matr;
m=M;
n=N;
if (N && M) { matr=new VARTYPE[m*n];
if (!matr) ERROR_MATRIX(1);
setmem(matr,sizeof(VARTYPE)*m*n,0); }
else { m=n=0; matr=(VARTYPE*)0; }
return *this;
}
template <class VARTYPE>
ostream& operator<<(ostream &out,Matrix<VARTYPE> &A)
{ for(int i=0,j;i<A.size_row();i++)
{ for(j=0;j<A.size_col();j++)
out << A(i,j)<< "  ";
out<<endl;
}
return out;
}
template <class VARTYPE>
int operator>>(istream &inp,Matrix<VARTYPE> &A)
{ for(int i=0,j;i<A.size_row();i++)
for(j=0;j<A.size_col();j++) if( !(inp>>A(i,j)) ) return 1;
return 0;
}
template <class VARTYPE>
void Matrix<VARTYPE>::swap_line(dim L1, dim L2)
{
if (L1==L2)
return;
double b;
for(int j=0;j<n;j++)
{
b=(*this)(L1,j);
(*this)(L1,j)=(*this)(L2,j);
(*this)(L2,j)=b;
}
}
template <class VARTYPE>
void Matrix<VARTYPE>::swap_column(dim C1, dim C2)
{
if (C1==C2)
return;
double b;
for(int i=0;i<m;i++)
{
b=(*this)(i,C1);
(*this)(i,C1)=(*this)(i,C2);
(*this)(i,C2)=b;
}
}
template <class VARTYPE>
dim Matrix<VARTYPE>::read(ifstream &finp)
{ (finp.get(m)).get(n); delete []matr; matr=new VARTYPE[m*n];
if(!matr) ERROR_MATRIX(1);
setmem(matr,sizeof(VARTYPE)*m*n,0);
finp.read((char *)matr,sizeof(VARTYPE)*m*n); return finp.fail();
}
template <class VARTYPE>
dim Matrix<VARTYPE>::write(ofstream &fout)
{ (fout.put(m)).put(n);
(fout.write((char *)matr,sizeof(VARTYPE)*m*n))<<flush; return fout.fail();
}
template <class VARTYPE>
VARTYPE operator%(const Matrix<VARTYPE> &A, const Matrix<VARTYPE>&B)
{
if(A.n!=1 || B.n!=1) A.ERROR_MATRIX(9);
if(A.m!=B.m) A.ERROR_MATRIX(0);
VARTYPE scalarmul = 0;
for(int i=0; i<A.m; i++)
scalarmul = scalarmul+A(i)*B(i);
return scalarmul;
}
template <class VARTYPE>
void Matrix<VARTYPE>::ERROR_MATRIX(dim E) const
{ static char *message[] = {
"Матрицы должны иметь одинаковую размерность",                  //0
"Не выделена память!",
//1
"Матрицы не согласованы для умножения",                                 //2
"Степень должна быть больше нуля или -1",                                //3
"Матрица должна быть квадратной",
//4
"Нулевой ведущий элемент в преобразовании Гаусса",               //5
"Вставка невозможна из-за перекрытия базовой матрицы",       //6
"Извлекаемая матрица выходит за границы базовой",                 //7
"Выход за границы. Попытка доступа к несущ. элементу",          //8
"Это не вектор!"};
//9
cerr<<"ERROR: "<< message[E] << endl; exit(1);
}


Вопрос по прежнему актуален. Можно ли сделать из него библиотеку matrix.lib ?
А можно сделать из этого кода хеадер-файл matrix.h и уже из matrix.h и matrix.срр (где main) сделать matrix.lib?
Кстати, а как делать библиотеку в Вижуал Студио 2005?

Это сообщение отредактировал(а) yorgan - 8.6.2008, 21:06
PM MAIL   Вверх
bronislav
Дата 8.6.2008, 21:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Цитата(yorgan @  8.6.2008,  20:02 Найти цитируемый пост)
Кстати, а как делать библиотеку в Вижуал Студио 2005?


Это вопрос для отдельного топика


Цитата(yorgan @  8.6.2008,  20:02 Найти цитируемый пост)
А можно сделать из этого кода хеадер-файл matrix.h и уже из matrix.h и matrix.срр (где main) сделать matrix.lib?


А как ты собораешься использовать такую библиотеку с main?


--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
Дата 8.6.2008, 21:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Видимо вот в чем собака зарыта. Преподаватель задал вопрос таким образом: можно ли сделать matrix.lib из matrix.h и matrix.cpp (где мэйн), значит с мэйном точно нельзя. А просто из matrix.h можно?
PM MAIL   Вверх
bronislav
Дата 8.6.2008, 21:41 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 334
Регистрация: 29.1.2008
Где: Украина::Донецк

Репутация: 2
Всего: 3



Только из заголовочного файла (.h) сделать библиотеку нельзя.




--------------------
user posted image
иногда проще и быстрей обойти лужу, даже если кажется что она мелкая и путь напрямик короче - ведь она может скрывать открытый люк (с) mes
PM MAIL   Вверх
yorgan
  Дата 8.6.2008, 21:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



хм... тогда возникает закономерный вопрос)))
А что еще нужно, если *.срр-файл с мэйном использовать нельзя ?

P.s. Код с шаблонным классом "матрица" можно сохранить как .cpp без мэна...

Это сообщение отредактировал(а) yorgan - 8.6.2008, 21:51
PM MAIL   Вверх
rrrFer
Дата 8.6.2008, 22:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 208
Регистрация: 11.5.2008
Где: Красноярск

Репутация: 0
Всего: 1



yorgan
Цитата

хм... тогда возникает закономерный вопрос)))
А что еще нужно, если *.срр-файл с мэйном использовать нельзя ?

наверно надо выделить все функции, кроме main в отдельный .cpp smile

Это сообщение отредактировал(а) rrrFer - 8.6.2008, 22:04
PM MAIL WWW ICQ   Вверх
bsa
Дата 9.6.2008, 11:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Для создания бинарной библиотеки (*.lib, *.a, *.dll, *.so) нужно создавать *.cpp файл. В него можно выделить только нешаблонные функции и методы нешаблонных классов.
Другими словами - из шаблонного класса бинарную библиотеку сделать нельзя, так как исходный код шаблона должен быть доступен во всех местах компиляции.

С другой стороны, просто библиотеки сделать можно. Типичный пример - boost. Там далеко не все библиотеки имеют бинарные составляющие.
PM   Вверх
yorgan
Дата 9.6.2008, 19:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Таким образом из шаблонных классов библиотеку не создать... а можно ее создать из нешаблонных классов smile
А можно вот это место поподробнее разжевать для тугодума?
Цитата(bsa @  9.6.2008,  11:45 Найти цитируемый пост)
так как исходный код шаблона должен быть доступен во всех местах компиляции.


Заранее спасибо!
PM MAIL   Вверх
bsa
Дата 9.6.2008, 20:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(yorgan @ 9.6.2008,  19:49)
А можно вот это место поподробнее разжевать для тугодума?
Цитата(bsa @  9.6.2008,  11:45 Найти цитируемый пост)
так как исходный код шаблона должен быть доступен во всех местах компиляции.

На самом деле нужен не весь исходный код, а только используемая часть. Более того, даже она не обязательна (это уже тонкости, и тебе заморачиваться на них не стоит). Даже в стандарте С++ есть упоминание возможности создания бинарных библиотек шаблонов, но, на сколько мне известно, ни один популярный компилятор этого делать не умеет.

Для того, чтобы ответить на этот вопрос нужно понимать, что такое шаблон. Шаблон - это программа этапа компиляции (т.е. ее выполняет компилятор), результатом работы которой является специализированная функция(класс), которая умеет работать только с указанными параметрами [шаблона] и ничем иным. Таких специализаций компилятор может нагородить кучу - по числу уникальных комбинаций параметров шаблона. Но чтобы ему создать специализацию шаблона, ему нужно иметь доступ к исходному тексту этого шаблона. Если шаблон - это класс, то должен быть доступ к тексту самого класса, а так же методов используемых в данном месте программы (методы, которые не используются в программе, проверяются только на синтаксические ошибки и более ни в чем не учавствуют).

Пример на пальцах (тех кто понимает, просьба не пинать, но красивее ничего не придумал), у тебя есть текст, ты хочешь одно определенное слово заменить на другое, не зная полностью этого слова (или даже зная только первую и последную буквы) ты корректно выполнить операцию не сможешь.
PM   Вверх
yorgan
Дата 11.6.2008, 00:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Цитата(bsa @  9.6.2008,  20:51 Найти цитируемый пост)
Шаблон - это программа этапа компиляции (т.е. ее выполняет компилятор), результатом работы которой является специализированная функция(класс), которая умеет работать только с указанными параметрами [шаблона] и ничем иным. Таких специализаций компилятор может нагородить кучу - по числу уникальных комбинаций параметров шаблона. Но чтобы ему создать специализацию шаблона, ему нужно иметь доступ к исходному тексту этого шаблона.

Извини за серость, а компилятор не имеет доступа к исходному тексту шаблона, если этот шаблон определен в библиотеке?
PM MAIL   Вверх
JackYF
Дата 11.6.2008, 01:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Цитата(yorgan @  10.6.2008,  23:19 Найти цитируемый пост)
если этот шаблон определен в библиотеке? 

Шаблон - это исходный код. Если библиотека не распространяется в исходных кодах, то шаблон в библиотеке определён быть не может.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
yorgan
Дата 11.6.2008, 15:13 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Цитата(JackYF @  11.6.2008,  01:47 Найти цитируемый пост)
Шаблон - это исходный код. Если библиотека не распространяется в исходных кодах, то шаблон в библиотеке определён быть не может. 

Что значит распространяется или не распространяется...
Преподаватель задал такой вопрос: Можно ли из твоего шаблонного класса матрица сделать библиотеку "matrix.lib" и будет ли она работать при подключении к другому проекту?
PM MAIL   Вверх
JackYF
Дата 11.6.2008, 16:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Бинарную - нет.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
yorgan
Дата 11.6.2008, 17:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Цитата(JackYF @  11.6.2008,  16:26 Найти цитируемый пост)
Бинарную - нет. 

почему?
Т.к.:
Цитата(bsa @  9.6.2008,  20:51 Найти цитируемый пост)
нужно иметь доступ к исходному тексту этого шаблона

Почему компилятор не имеет доступа к исходному тексту в бинарной библиотеке? А в какой библиотеке имеет доступ? Он что не может читать бинарные библиотеки или что?
PM MAIL   Вверх
JackYF
Дата 11.6.2008, 22:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Цитата(yorgan @  11.6.2008,  16:45 Найти цитируемый пост)
Почему компилятор не имеет доступа к исходному тексту в бинарной библиотеке?

Потому что бинарная библиотека она на то и бинарная, что исходников не содержит smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
yorgan
Дата 12.6.2008, 11:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



А какая разница описан ли шаблонный класс на языке С++ или в двоичном коде? А если создать бинарную библиотеку просто из класса (не шаблонного), то компилятор все хорошо будет читать и понимать?
PM MAIL   Вверх
fish9370
Дата 12.6.2008, 12:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 663
Регистрация: 15.4.2007
Где: Москва

Репутация: 1
Всего: 1



Цитата(yorgan @  12.6.2008,  11:10 Найти цитируемый пост)
А какая разница описан ли шаблонный класс на языке С++ или в двоичном коде?


а какая разница между типом int и переменной в памяти, которую создал компилятор с помощью типа int?

1. шаблон - это тип, передав определенные параметры в которй можно получить экземпляр объекта в памяти..
2. информация о типе никогда не содержится в бинарном файле..
3. экземпляр объекта - это двоичные данные в памяти (которые можно записать в двоичную библиотеку)
4. компилятор работает с исходным текстом, а процесс перевода (трансляции) из исходного текста в бинарный (машинный) код называется компиляцией..

исходя из выше сказанного ответь на свой вопрос сам..


--------------------
undefined
PM MAIL WWW ICQ   Вверх
yorgan
Дата 13.6.2008, 20:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



хорошо...
Я так понял не только шаблонный, но и простой класс нельзя сделать библиотекой?
Если да, то можно пример: что тогда можно сделать библиотекой?
PM MAIL   Вверх
JackYF
Дата 14.6.2008, 01:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Цитата(yorgan @  13.6.2008,  19:17 Найти цитируемый пост)
но и простой класс нельзя сделать библиотекой?

Неверно. Можно.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
yorgan
Дата 14.6.2008, 16:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Цитата(JackYF @  14.6.2008,  01:10 Найти цитируемый пост)
Неверно. Можно. 

ну, так библиотека из класса тоже будет бинарной... почему же тогда компилятор не сможет прочесть бинарную библиотеку с шаблонным классом, а с обычным классом сможет?
PM MAIL   Вверх
LavYaAll
Дата 14.6.2008, 18:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 62
Регистрация: 1.5.2008

Репутация: 1
Всего: 1



yorgan
Шаблон не компилируется, если не создан его экземпляр на основе какого-либо типа/класса. Компилятор его просто проигнорирует в этом случае. А это значит, что файл, полученный после компиляции не будет содержать информацию о шаблоне. Теперь ответь на вопрос. Как можно импортировать из библиотеки то, чего там нет?
Цитата(yorgan @  13.6.2008,  22:17 Найти цитируемый пост)
класс нельзя сделать библиотекой?

Можно. Потому что класс компилируется и заносится в файл, полученный после компиляции. И все же эти слова режут слух. Никто не делает класс библиотекой. Ты создаешь, к примеру, проект DLL(динамическая библиотека), а далее в нем описываешь класс, который при помощи директив __declspec(dllexport) или .DEF файла экспортируешь из этой библиотеки, если конечно хочешь. В библиотеке может быть сколько угодно классов. Да и не только классы могут быть, а еще и просто функции, переменные, ресурсы наконец.

PS. Про библиотеки можно почитать детально в книге: Дж. Рихтер - Windows для профессионалов Создание эффективных Win32-приложений с учетом специфики 64-разрядной версии Windows

Это сообщение отредактировал(а) LavYaAll - 14.6.2008, 19:41
PM   Вверх
bsa
Дата 14.6.2008, 23:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(yorgan @ 13.6.2008,  20:17)
Я так понял не только шаблонный, но и простой класс нельзя сделать библиотекой?

Видимо, ты не очень представляешь себе, что такое класс. Попробую объяснить на пальцах. Вот есть код:
Код
class MyClass
{
public:
   int x;
};
Для него не нужна библиотека, так как в библиотеки помещаются статические переменные класса и методы. Теперь напишем функцию, которая будет работать с экземляром этого класса:
Код
class MyClass
{
public:
   int x;
};
...
int my_func(MyClass *mc)
{
   mc->x = 1;
   return mc->x;
}
Вот эта функция и может быть размещена в библиотеке, это не удивляет, надеюсь?
Код
class MyClass
{
public:
   int x;
   int my_func();
};
...
int MyClass::my_func()
{
   this->x = 1;
   return x;
}
А теперь подумаем, что такое метод. И что такое указатель this. Оказывается, любому нестатическому методу в виде первого скрытого параметра передается указатель на экземляр класса. Т.е. в машинном коде эта функция будет выглядеть, как во втором примере!
PM   Вверх
yorgan
Дата 15.6.2008, 23:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Вот попытался в Вижуал студио 2005 создать библиотеки. Делал библиотеки из шаблонного класса, обычного класса и просто библиотека, которая содержала в себе одну функцию, возводящую в квадрат число типа инт. Везде результат один и тот же, а именно 100 ошибок smile
Вот видно все на скриншоте:

user posted image


http://dump.ru/file_catalog/650099
или http://slil.ru/25898509

Делал таким образом:
Create Project в Start Page, далее в Project Types выбирал Visual C++: Win32 -> Win32 Consol Application. Далее Static Library и галочка только на Precompiled header.

В проекте создавал один файл .cpp или .h куда помещал код класса (функции), и еще один файл .cpp, куда инклюдом подключал первый файл с кодом класса(функции). Библиотека компилилась без ошибок и предупреждений.
Но во всех случаях результат один - ошибки типа "Error C2018 unkonwn character 0x10" или похожие...

Что я не правильно делаю?
PM MAIL   Вверх
JackYF
Дата 16.6.2008, 00:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 6
Всего: 162



Во-первых, далеко не обязательно делать скриншот - не у всех толстые инет-каналы. Достаточно скопировать текст.

Во-вторых, библиотеки не включаются директивой #include, они включаются в найстроках линковки проекта.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
LavYaAll
Дата 16.6.2008, 08:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Awaiting Authorisation
Сообщений: 62
Регистрация: 1.5.2008

Репутация: 1
Всего: 1



yorgan, если ты создал статическую библиотеку *.lib, то подключить ее можно через Project--->Add Existing Item---->(выбираешь файл статической библиотеки) Только не забудь в фильтре указать: "All files", чтоб отобразились все файлы папки.

Это сообщение отредактировал(а) LavYaAll - 16.6.2008, 08:10
PM   Вверх
yorgan
Дата 16.6.2008, 09:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Спасибо. Теперь работает.
PM MAIL   Вверх
yorgan
Дата 19.6.2008, 23:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Правильно ли я понял, что можно сделать так:
Запихать в хедер файл само описание шаблонного класса, а в *.lib его методы? и будет работать?)
PM MAIL   Вверх
bsa
Дата 19.6.2008, 23:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(yorgan @ 19.6.2008,  23:17)
Правильно ли я понял, что можно сделать так:
Запихать в хедер файл само описание шаблонного класса, а в *.lib его методы? и будет работать?)

нет. нельзя в lib файл запихать методы шаблонного класса. Они должны быть в заголовочном файле
PM   Вверх
yorgan
  Дата 20.6.2008, 08:17 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 39
Регистрация: 5.6.2008

Репутация: нет
Всего: нет



Т.е. единственное, что можно это сделать из шаблонного класса хедер файл?
У меня преподаватель спросил, а как тогда организовывается библиотека STL, если из шаблонных классов нельзя создать библиотеку?
PM MAIL   Вверх
bsa
Дата 20.6.2008, 08:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 85
Всего: 196



Цитата(yorgan @ 20.6.2008,  08:17)
У меня преподаватель спросил, а как тогда организовывается библиотека STL, если из шаблонных классов нельзя создать библиотеку?

Из шаблонных классов нельзя создать БИНАРНУЮ библиотеку.
А просто библиотека может поставляться и в виде набора заголовочных файлов (boost::spirit, например). Как вариант, можно найти нешаблонную часть твоего шаблона, выделить ее и поместить в cpp файл. Но это очень редко выходит.
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "C/C++: Для новичков"
JackYF
bsa

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами

  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.2143 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.