2015-10-11 2 views
2

У меня проблемы с значением «p1.media». Значение носит медиа: 6.91026e-310 и должно быть как 1000, 5000, .... Я стараюсь слишком много решений, но кто-то работает. Вот код:Невозможно принять значение объекта - C++

Код Calculos.h

#ifndef CALCULOS_H 
#define CALCULOS_H 
//includes 
#define N 100 
using namespace std; 

class Calculos { 
public: 
    Calculos(double T[], int op); 
    Calculos(double T[], int op, double media); 
    Calculos(); //constructor por defecto 
    void run(); 

    int op; 
    double desvtipica, media, *T; 
}; 
#endif 

Кодекс Calculos.cpp

//includes 
#include "Calculos.h" 
using namespace std; 

Calculos::Calculos(double T[], int op) { 
    this->T = T; 
    this->op = op; 
    desvtipica = 0.0; 
}; 

Calculos::Calculos() { 
} 
Calculos::Calculos(double T[], int op, double media) { 
    this->T = T; 
    this->op = op; 
    this->media=media; 

}; 
void Calculos::run() { 
    if(op == 1) { //calcular media 
     double suma = 0.0; 
     for(int i = 0; i < N; i++) { 
      suma = suma + T[i]; 
     } 
     media = (double)(suma/N); 
    } 
    else { //op=3 calcular desviacion tipica 
     desvtipica = 3.0; //partially 
    } 
}; 

код из Ejercicio.cpp

//includes 
#include "Calculos.h" 
#include <iostream> 
#include <cstdlib> 
#include <thread> 

using namespace std; 

double fRand(double fMin, double fMax) 
{ 
    double f = (double)rand()/RAND_MAX; 
    return fMin + f * (fMax - fMin); 
}; 

int main() { 
    cout << "#datos: " << N << endl; 
    double T[N]; 
    for(int i = 0 ; i < N; i++) { 
     T[i] = fRand(1.0, 1000.0); 
    } 

    thread P[2]; 

    Calculos p1(T, 1); 
    P[0] = thread(&Calculos::run, p1); 
    P[0].join(); 
    double m = p1.media; // Here is the problem. p1.media return bad values 
    cout << "media: " << m << endl; 
    Calculos p3(T, 3, m); 
    P[1] = thread(&Calculos::run, p3); 
    P[1].join(); 

    cout << "Fin\n"; 
    return 0; 
} 
+2

Добро пожаловать в переполнение стека. Важно научиться * упрощать * ваши вопросы.Это не только для нашего удобства, это жизненный навык программирования. Если вы уменьшите проблему до [минимального примера конкуренции] (http://stackoverflow.com/help/mcve), вы, вероятно, обнаружите причину на этом пути, и даже если вы этого не сделаете, у вас будет очень простая проблема. показать нам. – Beta

+0

Кроме того, почему вы не исправляете ошибки компиляции? Ваш 'double calcular_desvtipica (...)' ничего не возвращает. – Beta

+0

Я упростил код настолько, насколько могу. У меня нет ошибки компиляции. Проблема заключается в том, чтобы принимать значение «media» из объекта –

ответ

5

Существует проблема в том, как вы передаете аргументы в конструктор thread.

изменение:

P[0] = thread(&Calculos::run, p1); // creates a copy of p1 

к:

P[0] = thread(&Calculos::run, std::ref(p1)); // pass p1 by reference 

Теперь выход:

#datos: 100 
media: 547.278 
Fin 

Примечания

Аргументы функции потока: перемещено или скопировано по значению. Если аргумент должен быть передан функции потока, его необходимо обернуть (например, с помощью std::ref или std::cref).

Источник: http://en.cppreference.com/w/cpp/thread/thread/thread (курсив мой)


В коде p1.media это 0, потому что вы ничего с ним не делать. Вы работали с временной копией p1.

+0

Ваше первое исправление фактически передается указателем, а не ссылкой (тот же эффект, что поток действует на тот же объект) –

+0

@BenVoigt Right, Thanks. Я удалил это. – sergej

3

Проблема заключается в использовании вами конструктора std::thread. См. Третье определение его here. Строка P[0] = thread(&Calculos::run, p1); создает копию из p1 и затем действует на нее. Попробуйте использовать простой ссылочный захват вместо:

P[0] = thread([&p1](){ p1.run(); }); 

Или, я полагаю, вы могли бы также попробовать переходящую в адресе p1 как это:

P[0] = thread(&Calculos::run, &p1); 

Я знаю, что этот синтаксис работает для таких std::bind , но я не уверен насчет std::thread.

Смежные вопросы